本文提供了一种对文件夹进行zip压缩并加密的方法。
添加依赖
cargo add anyhow
cargo add walkdir
cargo add zip
cargo add zip-extensions
计算文件夹的大小
目的是对需要压缩的文件夹的大小做一个限制。当然如果资源足够的话,可以去掉此限制。
rust
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();
}
压缩并加密文件夹
rust
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)
}
单元测试
rust
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);
}