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);
}
相关推荐
星栈17 小时前
10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用
前端·rust·前端框架
望眼欲穿的程序猿1 天前
读取芯片内部温度传感器
嵌入式硬件·rust
望眼欲穿的程序猿1 天前
ADC 模拟电压采集
嵌入式硬件·rust
codexu_4612291871 天前
NoteGen 里一条记录如何变成 Markdown
前端·笔记·rust·tauri
Rust研习社1 天前
Rust 错误处理的黄金搭档:一个定义错误,一个传播错误
后端·rust·编程语言
techdashen1 天前
绕过系统 ICMP:用 rawsock、Npcap 和 WMI 找到默认网卡
开发语言·arm开发·rust
小二·1 天前
Rust 后端实战:高性能 Web 服务开发全链路
开发语言·前端·rust
island13141 天前
【开源软件移植】把 RustDesk 的 Rust 核心搬到 HarmonyOS PC:一次 Native HAR 迁移实战记录
开发语言·rust·harmonyos
小二·1 天前
Rust 爬虫与数据处理实战:大规模并发抓取 + 流式处理
开发语言·爬虫·rust
techdashen1 天前
绕过 WMI:用 Rust 绑定 Win32 变长结构体和 UTF-16 字符串
开发语言·后端·rust