rust - 对文件夹进行zip压缩加密

本文提供了一种对文件夹进行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);
}
相关推荐
姜 萌@cnblogs3 小时前
开源我的一款自用AI阅读器,引流Web前端、Rust、Tauri、AI应用开发
rust·web·tauri·svelte
明月看潮生13 小时前
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型
开发语言·青少年编程·rust·编程与数学
Uncomfortableskiy18 小时前
Rust 官方文档:人话版翻译指南
开发语言·rust
大卫小东(Sheldon)19 小时前
GIM: 调用AI自动生成git提交消息的工具
git·rust
大G哥1 天前
Rust 之 trait 与泛型的奥秘
java·开发语言·jvm·数据结构·rust
Source.Liu2 天前
【typenum】 1 说明文件(README.md)
rust
蜗牛沐雨2 天前
Rust 中的 Pin 和 Unpin:内存安全与异步编程的守护者
服务器·开发语言·rust
hrrrrb2 天前
【Rust】枚举和模式匹配
开发语言·rust
zhuziheniaoer2 天前
rust-candle学习笔记12-实现因果注意力
笔记·学习·自然语言处理·rust
无名之逆2 天前
Hyperlane: Unleash the Power of Rust for High-Performance Web Services
java·开发语言·前端·后端·http·rust·web