use std::fs;
use std::io::Write;
use std::path::Path;
use zip::unstable::write::FileOptionsExt;
fn main() {
let test_dir = r"d:\workspace\win-rar\test-data";
let output_dir = r"d:\workspace\win-rar\test-data\output";
let _ = fs::create_dir_all(output_dir);
println!("=== WinRAR 可用性测试 ===\n");
print_test("1. ZIP 压缩(单文件)");
test_zip_compress_single(test_dir, output_dir);
print_test("2. ZIP 压缩(多文件)");
test_zip_compress_multi(test_dir, output_dir);
print_test("3. ZIP 解压");
test_zip_extract(output_dir);
print_test("4. 7Z 压缩");
test_7z_compress(test_dir, output_dir);
print_test("5. 7Z 解压");
test_7z_extract(output_dir);
print_test("6. TAR.GZ 压缩与解压");
test_targz(test_dir, output_dir);
print_test("7. TAR.BZ2 压缩与解压");
test_tarbz2(test_dir, output_dir);
print_test("8. TAR.XZ 压缩与解压");
test_tarxz(test_dir, output_dir);
print_test("9. ZIP 带密码压缩与解压");
test_zip_password(test_dir, output_dir);
print_test("10. 7Z 带密码压缩与解压");
test_7z_password(test_dir, output_dir);
print_test("11. 文件夹压缩(ZIP)");
test_folder_compress(test_dir, output_dir);
print_test("12. 列出归档内容");
test_list_archive(output_dir);
println!("\n=== 测试完成 ===");
}
fn print_test(name: &str) {
println!("\n--- {} ---", name);
}
fn test_zip_compress_single(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\single.zip", output_dir);
let file = std::fs::File::create(&output).expect("创建zip失败");
let mut zip = zip::ZipWriter::new(file);
let options = zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Deflated);
let data = std::fs::read(format!(r"{}\test1.txt", test_dir)).expect("读取文件失败");
zip.start_file("test1.txt", options).expect("start_file失败");
zip.write_all(&data).expect("write失败");
zip.finish().expect("finish失败");
println!(" OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
}
fn test_zip_compress_multi(test_dir: &str, output_dir: &str) {
let files = vec![
format!(r"{}\test1.txt", test_dir),
format!(r"{}\test2.txt", test_dir),
format!(r"{}\test3.txt", test_dir),
];
let output = format!(r"{}\multi.zip", output_dir);
let file = std::fs::File::create(&output).expect("创建zip失败");
let mut zip = zip::ZipWriter::new(file);
let options = zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Deflated);
for f in &files {
let name = Path::new(f).file_name().unwrap().to_string_lossy().to_string();
let data = std::fs::read(f).expect("读取文件失败");
zip.start_file(&name, options).expect("start_file失败");
zip.write_all(&data).expect("write失败");
}
zip.finish().expect("finish失败");
println!(" OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
}
fn test_zip_extract(output_dir: &str) {
let zip_path = format!(r"{}\multi.zip", output_dir);
let extract_dir = format!(r"{}\zip_extracted", output_dir);
let _ = fs::create_dir_all(&extract_dir);
let file = std::fs::File::open(&zip_path).expect("打开zip失败");
let mut archive = zip::ZipArchive::new(file).expect("读取zip失败");
for i in 0..archive.len() {
let mut entry = archive.by_index(i).expect("读取条目失败");
let name = entry.name().to_string();
let out_path = format!(r"{}\{}", extract_dir, name);
let mut out_file = std::fs::File::create(&out_path).expect("创建输出文件失败");
std::io::copy(&mut entry, &mut out_file).expect("写入失败");
println!(" 解压: {} ({} bytes)", name, entry.size());
}
println!(" OK: 解压到 {}", extract_dir);
}
fn test_7z_compress(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\test.7z", output_dir);
let files = vec![
format!(r"{}\test1.txt", test_dir),
format!(r"{}\test2.txt", test_dir),
];
let mut writer = sevenz_rust::SevenZWriter::create(&output)
.expect("SevenZWriter创建失败");
for f in &files {
let name = Path::new(f).file_name().unwrap().to_string_lossy().to_string();
let entry = sevenz_rust::SevenZArchiveEntry::from_path(f, name);
let file = std::fs::File::open(f).expect("打开文件失败");
writer.push_archive_entry(entry, Some(file)).expect("push失败");
}
writer.finish().expect("finish失败");
println!(" OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
}
fn test_7z_extract(output_dir: &str) {
let sz_path = format!(r"{}\test.7z", output_dir);
let extract_dir = format!(r"{}\7z_extracted", output_dir);
let _ = fs::create_dir_all(&extract_dir);
sevenz_rust::decompress_file(&sz_path, &extract_dir)
.expect("7z解压失败");
for entry in fs::read_dir(&extract_dir).expect("读取目录失败") {
let entry = entry.expect("entry失败");
let path = entry.path();
if path.is_file() {
let len = std::fs::metadata(&path).unwrap().len();
println!(" 解压: {} ({} bytes)", path.file_name().unwrap().to_string_lossy(), len);
}
}
println!(" OK: 解压到 {}", extract_dir);
}
fn test_targz(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\test.tar.gz", output_dir);
let extract_dir = format!(r"{}\targz_extracted", output_dir);
let _ = fs::create_dir_all(extract_dir.clone());
let file = std::fs::File::create(&output).expect("创建tar.gz失败");
let enc = flate2::write::GzEncoder::new(file, flate2::Compression::default());
let mut tar = tar::Builder::new(enc);
let data1 = std::fs::read(format!(r"{}\test1.txt", test_dir)).expect("读取test1失败");
let data2 = std::fs::read(format!(r"{}\test2.txt", test_dir)).expect("读取test2失败");
let mut header1 = tar::Header::new_gnu();
header1.set_path("test1.txt").expect("set_path失败");
header1.set_size(data1.len() as u64);
header1.set_mode(0o644);
header1.set_cksum();
tar.append(&header1, &*data1).expect("append失败");
let mut header2 = tar::Header::new_gnu();
header2.set_path("test2.txt").expect("set_path失败");
header2.set_size(data2.len() as u64);
header2.set_mode(0o644);
header2.set_cksum();
tar.append(&header2, &*data2).expect("append失败");
let enc = tar.into_inner().expect("into_inner失败");
enc.finish().expect("finish失败");
println!(" 压缩 OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
let file = std::fs::File::open(&output).expect("打开tar.gz失败");
let dec = flate2::read::GzDecoder::new(file);
let mut archive = tar::Archive::new(dec);
archive.unpack(&extract_dir).expect("解压失败");
println!(" 解压 OK: {}", extract_dir);
}
fn test_tarbz2(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\test.tar.bz2", output_dir);
let extract_dir = format!(r"{}\tarbz2_extracted", output_dir);
let _ = fs::create_dir_all(extract_dir.clone());
let file = std::fs::File::create(&output).expect("创建tar.bz2失败");
let enc = bzip2::write::BzEncoder::new(file, bzip2::Compression::default());
let mut tar = tar::Builder::new(enc);
let data1 = std::fs::read(format!(r"{}\test1.txt", test_dir)).expect("读取test1失败");
let mut header1 = tar::Header::new_gnu();
header1.set_path("test1.txt").expect("set_path失败");
header1.set_size(data1.len() as u64);
header1.set_mode(0o644);
header1.set_cksum();
tar.append(&header1, &*data1).expect("append失败");
let enc = tar.into_inner().expect("into_inner失败");
enc.finish().expect("finish失败");
println!(" 压缩 OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
let file = std::fs::File::open(&output).expect("打开tar.bz2失败");
let dec = bzip2::read::BzDecoder::new(file);
let mut archive = tar::Archive::new(dec);
archive.unpack(&extract_dir).expect("解压失败");
println!(" 解压 OK: {}", extract_dir);
}
fn test_tarxz(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\test.tar.xz", output_dir);
let extract_dir = format!(r"{}\tarxz_extracted", output_dir);
let _ = fs::create_dir_all(extract_dir.clone());
let file = std::fs::File::create(&output).expect("创建tar.xz失败");
let enc = xz2::write::XzEncoder::new(file, 6);
let mut tar = tar::Builder::new(enc);
let data1 = std::fs::read(format!(r"{}\test1.txt", test_dir)).expect("读取test1失败");
let mut header1 = tar::Header::new_gnu();
header1.set_path("test1.txt").expect("set_path失败");
header1.set_size(data1.len() as u64);
header1.set_mode(0o644);
header1.set_cksum();
tar.append(&header1, &*data1).expect("append失败");
let enc = tar.into_inner().expect("into_inner失败");
enc.finish().expect("finish失败");
println!(" 压缩 OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
let file = std::fs::File::open(&output).expect("打开tar.xz失败");
let dec = xz2::read::XzDecoder::new(file);
let mut archive = tar::Archive::new(dec);
archive.unpack(&extract_dir).expect("解压失败");
println!(" 解压 OK: {}", extract_dir);
}
fn test_zip_password(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\encrypted.zip", output_dir);
let extract_dir = format!(r"{}\zip_encrypted_extracted", output_dir);
let _ = fs::create_dir_all(extract_dir.clone());
let file = std::fs::File::create(&output).expect("创建zip失败");
let mut zip = zip::ZipWriter::new(file);
let options = zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Deflated)
.with_deprecated_encryption(b"test123");
let data = std::fs::read(format!(r"{}\test1.txt", test_dir)).expect("读取文件失败");
zip.start_file("test1.txt", options).expect("start_file失败");
zip.write_all(&data).expect("write失败");
zip.finish().expect("finish失败");
println!(" 压缩 OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
let file = std::fs::File::open(&output).expect("打开zip失败");
let mut archive = zip::ZipArchive::new(file).expect("读取zip失败");
for i in 0..archive.len() {
let mut entry = archive.by_index_decrypt(i, b"test123").expect("解密失败");
let name = entry.name().to_string();
let out_path = format!(r"{}\{}", extract_dir, name);
let mut out_file = std::fs::File::create(&out_path).expect("创建输出文件失败");
std::io::copy(&mut entry, &mut out_file).expect("写入失败");
println!(" 解压: {} ({} bytes)", name, entry.size());
}
println!(" 解压 OK: {}", extract_dir);
}
fn test_7z_password(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\encrypted.7z", output_dir);
let extract_dir = format!(r"{}\7z_encrypted_extracted", output_dir);
let _ = fs::create_dir_all(extract_dir.clone());
let mut writer = sevenz_rust::SevenZWriter::create(&output)
.expect("SevenZWriter创建失败");
let pwd = sevenz_rust::Password::from("test123");
writer.set_content_methods(vec![
sevenz_rust::AesEncoderOptions::new(pwd).into(),
sevenz_rust::SevenZMethod::LZMA2.into(),
]);
let f_path = format!(r"{}\test1.txt", test_dir);
let entry = sevenz_rust::SevenZArchiveEntry::from_path(&f_path, "test1.txt".to_string());
let f = std::fs::File::open(&f_path).expect("打开文件失败");
writer.push_archive_entry(entry, Some(f)).expect("push失败");
writer.finish().expect("finish失败");
println!(" 压缩 OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
let pwd = sevenz_rust::Password::from("test123");
sevenz_rust::decompress_file_with_password(&output, &extract_dir, pwd)
.expect("7z密码解压失败");
for entry in fs::read_dir(&extract_dir).expect("读取目录失败") {
let entry = entry.expect("entry失败");
let path = entry.path();
if path.is_file() {
let len = std::fs::metadata(&path).unwrap().len();
println!(" 解压: {} ({} bytes)", path.file_name().unwrap().to_string_lossy(), len);
}
}
println!(" 解压 OK: {}", extract_dir);
}
fn test_folder_compress(test_dir: &str, output_dir: &str) {
let output = format!(r"{}\folder.zip", output_dir);
let folder = format!(r"{}\subdir", test_dir);
let file = std::fs::File::create(&output).expect("创建zip失败");
let mut zip = zip::ZipWriter::new(file);
let options = zip::write::SimpleFileOptions::default()
.compression_method(zip::CompressionMethod::Deflated);
zip.add_directory("subdir/", options).expect("add_directory失败");
for entry in fs::read_dir(&folder).expect("读取目录失败") {
let entry = entry.expect("entry失败");
let path = entry.path();
if path.is_file() {
let name = format!("subdir/{}", path.file_name().unwrap().to_string_lossy());
let data = fs::read(&path).expect("读取文件失败");
zip.start_file(&name, options).expect("start_file失败");
zip.write_all(&data).expect("write失败");
println!(" 添加: {}", name);
}
}
zip.finish().expect("finish失败");
println!(" OK: {} ({} bytes)", output, std::fs::metadata(&output).unwrap().len());
}
fn test_list_archive(output_dir: &str) {
let zip_path = format!(r"{}\multi.zip", output_dir);
let file = std::fs::File::open(&zip_path).expect("打开zip失败");
let mut archive = zip::ZipArchive::new(file).expect("读取zip失败");
println!(" ZIP 内容 ({} 个文件):", archive.len());
for i in 0..archive.len() {
let entry = archive.by_index(i).expect("读取条目失败");
println!(" {} - {} bytes (压缩: {} bytes)", entry.name(), entry.size(), entry.compressed_size());
}
let sz_path = format!(r"{}\test.7z", output_dir);
let len = std::fs::metadata(&sz_path).unwrap().len();
let file = std::fs::File::open(&sz_path).expect("打开7z失败");
let reader = sevenz_rust::SevenZReader::new(file, len, sevenz_rust::Password::empty())
.expect("SevenZReader创建失败");
let files = &reader.archive().files;
println!(" 7Z 内容 ({} 个文件):", files.len());
for f in files {
println!(" {} - {} bytes", f.name(), f.size());
}
}