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);
}
相关推荐
咚为2 分钟前
告别 lazy_static:深度解析 Rust OnceCell 的前世今生与实战
开发语言·后端·rust
Java水解16 小时前
Rust异步编程实战:构建高性能网络应用
后端·rust
土豆125017 小时前
Rust 实战:手把手教你开发一个命令行工具
前端·rust
勇敢牛牛_17 小时前
【aiway】基于 Rust 开发的 API + AI 网关
开发语言·后端·网关·ai·rust
Source.Liu1 天前
【Iced】`lib.rs` 源码分析 - `iced_core` 核心库
rust·iced
古城小栈1 天前
Rust跨平台编译打包 之 三大战役
开发语言·后端·rust
was1721 天前
基于 Rust 的跨 Shell 提示符:Starship 安装与环境初始化指南
开发语言·elasticsearch·rust
rainchestnut2 天前
bevy初体验2-官方示例学习
rust
葡萄城技术团队2 天前
Hurley:用 Rust 打造的高性能 HTTP 客户端 + 压测工具
开发语言·http·rust
Source.Liu2 天前
【dxf-rs】库全面介绍
rust·dxf-rs