rust zip库使用

180it 2023-03-06 PM 622℃ 0条

rust zip库使用

Cargo.toml增加依赖
zip = "0.5.5"

压缩目录使用

walkdir = "2"

use std::fs;
use std::fs::File;
use std::io::{copy, Read, Seek, Write};
use std::path::Path;
use std::str;
 
use walkdir::{DirEntry, WalkDir};
use zip::write::FileOptions;
/// 都没有进行错误处理,本例子是参考官方例子,其中压缩目录也是看官方例子使用了walkdir库
fn main() {
    compress_dir(Path::new("d:/tmp"), Path::new("d:/tmp.zip"));
    // compress_file(Path::new("d:/企业微信截图_15792418969249.png"), Path::new("d:/test.zip"));
    extract(Path::new("d:/tmp.zip"), Path::new("d:/tmp1"));
}
 
 
/// 压缩文件夹
/// test文件夹下有a.jpg和b.txt 两个文件
/// 压缩成test.zip文件
fn compress_dir(src_dir: &Path, target: &Path) {
    let zipfile = std::fs::File::create(target).unwrap();
    let dir = WalkDir::new(src_dir);
    zip_dir(&mut dir.into_iter().filter_map(|e| e.ok()), src_dir.to_str().unwrap(), zipfile);
}
/// 压缩文件
fn compress_file(src_dir: &Path, target: &Path) {
    let zipfile = std::fs::File::create(target).unwrap();
    let dir = WalkDir::new(src_dir);
 
    // src_dir.parent().map( |p| println!("{:?}",p.to_str().unwrap()));
    let prefix = src_dir.parent().map_or_else(||"/",|p|p.to_str().unwrap());
    zip_dir(&mut dir.into_iter().filter_map(|e| e.ok()), prefix, zipfile);
}
 
 
fn zip_dir<T>(it: &mut dyn Iterator<Item=DirEntry>, prefix: &str, writer: T) -> zip::result::ZipResult<()>
    where T: Write + Seek {
    let mut zip = zip::ZipWriter::new(writer);
    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Bzip2)//直接用了bzip2压缩方式,其它参看枚举
        .unix_permissions(0o755);//unix系统权限
 
    let mut buffer = Vec::new();
    for entry in it {
        let path = entry.path();
        //zip压缩一个文件时,会把它的全路径当成文件名(在下面的解压函数中打印文件名可知)
        //这里是去掉目录前缀
        println!("prefix  {:?} ...", prefix);
        let name = path.strip_prefix(Path::new(prefix)).unwrap();
        println!("name  {:?} ...", name);
        // Write file or directory explicitly
        // Some unzip tools unzip files with directory paths correctly, some do not!
        if path.is_file() {
            println!("adding file {:?} as {:?} ...", path, name);
            zip.start_file_from_path(name, options)?;
            let mut f = File::open(path)?;
 
            f.read_to_end(&mut buffer)?;
            zip.write_all(&*buffer)?;
            buffer.clear();
        } else if name.as_os_str().len() != 0 {//目录
            // Only if not root! Avoids path spec / warning
            // and mapname conversion failed error on unzip
            println!("adding dir {:?} as {:?} ...", path, name);
            zip.add_directory_from_path(name, options)?;
        }
    }
    zip.finish()?;
    Result::Ok(())
}
 
 
///解压
/// test.zip文件解压到d:/test文件夹下
///
fn extract(test: &Path, mut target: &Path) {
    let zipfile = std::fs::File::open(&test).unwrap();
    let mut zip = zip::ZipArchive::new(zipfile).unwrap();
 
    if !target.exists() {
        fs::create_dir_all(target).map_err(|e| {
            println!("{}", e);
        });
    }
    for i in 0..zip.len() {
        let mut file = zip.by_index(i).unwrap();
        println!("Filename: {} {:?}", file.name(), file.sanitized_name());
        if file.is_dir() {
            println!("file utf8 path {:?}", file.name_raw());//文件名编码,在windows下用winrar压缩的文件夹,中文文夹件会码(发现文件名是用操作系统本地编码编码的,我的电脑就是GBK),本例子中的压缩的文件再解压不会出现乱码
            let target = target.join(Path::new(&file.name().replace("\\", "")));
            fs::create_dir_all(target).unwrap();
        } else {
            let file_path = target.join(Path::new(file.name()));
            let mut target_file = if !file_path.exists() {
                println!("file path {}", file_path.to_str().unwrap());
                fs::File::create(file_path).unwrap()
            } else {
                fs::File::open(file_path).unwrap()
            };
            copy(&mut file, &mut target_file);
            // target_file.write_all(file.read_bytes().into());
        }
    }
}
 
 
fn create_dir(path: &Path) -> Result<(), std::io::Error> {
    fs::create_dir_all(path)
}
 

原文链接:https://blog.csdn.net/u013195275/article/details/105973490

支付宝打赏支付宝打赏 微信打赏微信打赏

如果文章或资源对您有帮助,欢迎打赏作者。一路走来,感谢有您!

标签: none

rust zip库使用