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);
}
相关推荐
a cool fish(无名)9 小时前
rust-方法语法
开发语言·后端·rust
a cool fish(无名)1 天前
rust-参考与借用
java·前端·rust
叶 落1 天前
[Rust 基础课程]猜数字游戏-获取用户输入并打印
rust·rust基础
RustFS1 天前
RustFS 如何修改默认密码?
rust
景天科技苑1 天前
【Rust线程池】如何构建Rust线程池、Rayon线程池用法详细解析
开发语言·后端·rust·线程池·rayon·rust线程池·rayon线程池
该用户已不存在2 天前
Zig想要取代Go和Rust,它有资格吗
前端·后端·rust
用户1774125612442 天前
不懂装懂的AI,折了程序员的阳寿
rust
量子位3 天前
vivo自研蓝河操作系统内核开源!Rust开发新机遇来了
rust·ai编程
祈澈菇凉3 天前
rust嵌入式开发零基础入门教程(六)
stm32·单片机·rust
祈澈菇凉3 天前
rust嵌入式开发零基础入门教程(二)
开发语言·后端·rust