本文提供了一种对文件夹进行zip压缩并加密的方法。
添加依赖
cargo add anyhow
cargo add walkdir
cargo add zip
cargo add zip-extensions
计算文件夹的大小
目的是对需要压缩的文件夹的大小做一个限制。当然如果资源足够的话,可以去掉此限制。
let mut total_size: u64 = 0;// 计算文件夹的大小for metadata in WalkDir::new(source_dir).min_depth(1).max_depth(max_depth).into_iter()// 忽略正在运行的进程或无权访问的目录.filter_map(|entry| entry.ok()).filter_map(|entry| entry.metadata().ok())// 只计算文件.filter(|metadata| metadata.is_file()){total_size += metadata.len();}
压缩并加密文件夹
use anyhow::Result;
use std::io::Write;
use std::{fs, path::Path};
use walkdir::WalkDir;
use zip::unstable::write::FileOptionsExt;
use zip::{write::FileOptions, CompressionMethod, ZipWriter};
use zip_extensions::zip_create_from_directory_with_options;/// 使用zip格式压缩文件夹,并返回原文件夹的大小
pub fn zip_directory(key: Vec<u8>,source_dir: &Path,archive_file: &Path,max_depth: usize,
) -> Result<u64> {let mut total_size: u64 = 0;// 计算文件夹的大小for metadata in WalkDir::new(source_dir).min_depth(1).max_depth(max_depth).into_iter()// 忽略正在运行的进程或无权访问的目录.filter_map(|entry| entry.ok()).filter_map(|entry| entry.metadata().ok())// 只计算文件.filter(|metadata| metadata.is_file()){total_size += metadata.len();// todo 可以在此对文件夹大小上限进行判断,如果超出上限,则// return Ok(total_size);}// 压缩加密文件夹let options = FileOptions::default().compression_method(CompressionMethod::DEFLATE).with_deprecated_encryption(&key);zip_create_from_directory_with_options(&archive_file.to_path_buf(),&source_dir.to_path_buf(),options,).unwrap();Ok(total_size)
}
单元测试
use std::env;#[test]
fn test_zip_directory() {let src_file_path = env::current_dir().unwrap().join("tests");let dst_file_path = env::current_dir().unwrap().join("tests.zip");let key = get_random_key16();let _ = zip_directory(key.to_vec(), &src_file_path, &dst_file_path, 10);
}