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);
}
相关推荐
Amos_Web16 小时前
Rust实战教程--文件管理命令行工具
前端·rust·全栈
alwaysrun19 小时前
Rust中字符串与格式化
rust·display·格式化·string·str·精度
魔镜前的帅比19 小时前
(开源项目)XSUN_DESKTOP_PET 2 (桌面宠物)
rust·宠物·tauri2
0110_102420 小时前
tauri + rust的环境搭建---初始化以及构建
开发语言·后端·rust
像风一样自由202020 小时前
Rust Tokio vs Go net/http:云原生与嵌入式生态选型指南
开发语言·golang·rust
大鱼七成饱2 天前
Rust Web 初学者必看:用一个宏搞定错误处理和统一返回
rust
Vallelonga2 天前
Rust 设计模式 Marker Trait + Blanket Implementation
开发语言·设计模式·rust
ftpeak2 天前
《Cargo 参考手册》第二十一章:Cargo 包命令
开发语言·rust
Source.Liu2 天前
【BuildFlow & 筑流】品牌命名与项目定位说明
c++·qt·rust·markdown·librecad
ftpeak2 天前
《Cargo 参考手册》第二十二章:发布命令
开发语言·rust