Rust ZIP压缩扩展库zip-extensions的使用,为ZIP文件操作提供额外功能和增强支持

Rust ZIP压缩扩展库zip-extensions的使用,为ZIP文件操作提供额外功能和增强支持

配置依赖

Cargo.toml文件中添加以下依赖:

[dependencies]
zip = "3.0"
zip-extensions = "0.8.3"

示例用法

将存档提取到目录

ZipArchiveExtensions trait提供了extract方法,可用于将存档解压缩到目录:

use std::fs::File;
use zip_extensions::read::ZipArchiveExtensions;
...

let file = File::create(archive_file)?;
let mut archive = zip::ZipArchive::new(file)?;
archive.extract(&target_path)?;

或者可以使用zip_extract助手函数:

use zip_extensions::*;
...
let archive_file: PathBuf = ...
let target_dir: PathBuf = ...
zip_extract(&archive_file, &target_dir)?;

将存档条目提取到内存

zip_extract_file_to_memory方法可用于将条目即时提取到内存:

use zip_extensions::*;

let archive_file = PathBuf::from_str(r#"Baloo_Da_2.zip"#)?;
let entry_path = PathBuf::from_str("BalooDa2-Medium.ttf")?;

let mut buffer : Vec<u8> = vec![];
match zip_extract_file_to_memory(&archive_file, &entry_path, &mut buffer) {
    Ok(()) => { println!("Extracted {} bytes from archive.", buffer.len()) },
    Err(e) => { println!("The entry does not exist.") }
};

从目录创建存档

ZipWriterExtensions trait提供了create_from_directorycreate_from_directory_with_options方法,可用于将整个目录层次结构添加到存档:

use zip::ZipWriter;
use zip_extensions::write::ZipWriterExtensions;
...

let file = File::create(archive_file)?;
let zip = ZipWriter::new(file);
zip.create_from_directory(&source_path)?;

或者可以使用zip_create_from_directory助手函数:

use zip_extensions::*;
...
let archive_file: PathBuf = ...
let source_dir: PathBuf = ...
zip_create_from_directory(&archive_file, &source_dir)?;

完整示例代码

use std::fs::File;
use std::path::PathBuf;
use zip_extensions::read::ZipArchiveExtensions;
use zip_extensions::write::ZipWriterExtensions;
use zip::ZipWriter;

// 解压ZIP文件示例
fn extract_zip_example() -> Result<(), Box<dyn std::error::Error>> {
    // 创建目标目录
    let target_dir = PathBuf::from("extracted");
    std::fs::create_dir_all(&target_dir)?;
    
    // 打开ZIP文件并解压
    let zip_file = File::open("example.zip")?;
    let mut archive = zip::ZipArchive::new(zip_file)?;
    archive.extract(&target_dir)?;
    
    Ok(())
}

// 从目录创建ZIP文件示例
fn create_zip_example() -> Result<(), Box<dyn std::error::Error>> {
    // 创建ZIP文件
    let output_file = File::create("output.zip")?;
    let zip_writer = ZipWriter::new(output_file);
    
    // 从目录创建ZIP
    let source_dir = PathBuf::from("source_directory");
    zip_writer.create_from_directory(&source_dir)?;
    
    Ok(())
}

// 提取单个文件到内存示例
fn extract_to_memory_example() -> Result<(), Box<dyn std::error::Error>> {
    let archive_file = PathBuf::from("example.zip");
    let entry_path = PathBuf::from("important_file.txt");
    
    let mut buffer: Vec<u8> = Vec::new();
    zip_extensions::zip_extract_file_to_memory(&archive_file, &entry_path, &mut buffer)?;
    
    println!("Extracted file content: {}", String::from_utf8_lossy(&buffer));
    
    Ok(())
}

fn main() {
    extract_zip_example().unwrap();
    create_zip_example().unwrap();
    extract_to_memory_example().unwrap();
}

这个扩展库为Rust的标准ZIP操作提供了更高层次的抽象,简化了常见的ZIP文件操作任务,如目录提取、创建和内存操作等。


1 回复

Rust ZIP压缩扩展库zip-extensions使用指南

概述

zip-extensions是一个Rust库,为标准的zip库提供了额外的功能和增强支持,简化了ZIP文件操作。它为常见的ZIP操作提供了更简洁的API,并添加了一些实用功能。

安装

Cargo.toml中添加依赖:

[dependencies]
zip-extensions = "0.1"

主要功能

  1. 简化ZIP文件创建和提取
  2. 支持递归目录压缩
  3. 提供更友好的错误处理
  4. 添加进度回调支持
  5. 增强的文件属性设置

基本使用方法

创建ZIP文件

use zip_extensions::zip_create_from_directory;

fn main() -> std::io::Result<()> {
    zip_create_from_directory(
        "archive.zip",  // 输出ZIP文件路径
        "src",          // 要压缩的目录
        zip::CompressionMethod::Deflated,  // 压缩方法
    )?;
    Ok(())
}

解压ZIP文件

use zip_extensions::zip_extract;

fn main() -> std::io::Result<()> {
    zip_extract(
        "archive.zip",  // ZIP文件路径
        "output_dir",   // 解压目标目录
    )?;
    Ok(())
}

高级功能

带进度回调的压缩

use zip_extensions::{zip_create_from_directory_with_progress, ProgressCallback};

fn progress_callback(path: &str, current: u64, total: u64) {
    println!("压缩中: {} - {}/{}", path, current, total);
}

fn main() -> std::io::Result<()> {
    zip_create_from_directory_with_progress(
        "archive.zip",
        "src",
        zip::CompressionMethod::Deflated,
        progress_callback,
    )?;
    Ok(())
}

选择性压缩文件

use zip_extensions::zip_create_from_directory_with_filter;

fn main() -> std::io::Result<()> {
    zip_create_from_directory_with_filter(
        "archive.zip",
        "src",
        zip::CompressionMethod::Deflated,
        |path| {
            // 只压缩.rs文件
            path.ends_with(".rs")
        },
    )?;
    Ok(())
}

设置文件权限(Unix系统)

use std::os::unix::fs::PermissionsExt;
use zip_extensions::zip_create_from_directory_with_permissions;

fn main() -> std::io::Result<()> {
    zip_create_from_directory_with_permissions(
        "archive.zip",
        "src",
        zip::CompressionMethod::Deflated,
        |path| {
            // 设置可执行权限
            if path.ends_with(".sh") {
                Some(0o755)  // rwxr-xr-x
            } else {
                Some(0o644)  // rw-r--r--
            }
        },
    )?;
    Ok(())
}

错误处理

zip-extensions提供了更友好的错误类型ZipExtensionsError:

use zip_extensions::{ZipExtensionsError, zip_extract};

fn main() -> Result<(), ZipExtensionsError> {
    match zip_extract("archive.zip", "output_dir") {
        Ok(_) => println!("解压成功"),
        Err(ZipExtensionsError::FileNotFound(path)) => {
            eprintln!("文件未找到: {}", path)
        },
        Err(e) => eprintln!("解压失败: {}", e),
    }
    Ok(())
}

完整示例

下面是一个完整的示例,展示了如何使用zip-extensions进行文件压缩和解压:

use std::path::Path;
use zip_extensions::{
    zip_create_from_directory_with_progress, 
    zip_extract,
    ProgressCallback,
    ZipExtensionsError
};

// 进度回调函数
fn progress_callback(path: &str, current: u64, total: u64) {
    println!("处理中: {} - 已处理: {} / 总计: {}", path, current, total);
}

fn main() -> Result<(), ZipExtensionsError> {
    // 1. 创建ZIP文件
    let source_dir = "test_data";
    let zip_file = "archive.zip";
    
    // 创建测试目录和文件
    if !Path::new(source_dir).exists() {
        std::fs::create_dir(source_dir)?;
        std::fs::write(format!("{}/file1.txt", source_dir), "测试文件1")?;
        std::fs::write(format!("{}/file2.rs", source_dir), "测试Rust文件")?;
    }

    println!("正在创建ZIP文件...");
    zip_create_from_directory_with_progress(
        zip_file,
        source_dir,
        zip::CompressionMethod::Deflated,
        progress_callback,
    )?;
    println!("ZIP文件创建成功: {}", zip_file);

    // 2. 解压ZIP文件
    let extract_dir = "extracted_data";
    println!("\n正在解压ZIP文件到 {}...", extract_dir);
    zip_extract(zip_file, extract_dir)?;
    println!("解压完成");

    // 验证解压的文件
    let extracted_file1 = format!("{}/file1.txt", extract_dir);
    let extracted_file2 = format!("{}/file2.rs", extract_dir);
    
    if Path::new(&extracted_file1).exists() && Path::new(&extracted_file2).exists() {
        println!("验证成功: 所有文件已正确解压");
    } else {
        eprintln!("验证失败: 部分文件未正确解压");
    }

    Ok(())
}

注意事项

  1. 对于大文件操作,考虑使用带进度回调的版本
  2. 在Windows和Unix系统上,文件权限的处理方式不同
  3. 默认情况下,符号链接不会被跟随
  4. 压缩大量小文件时,内存使用可能会增加

zip-extensions库通过简化常见操作和添加实用功能,使得在Rust中处理ZIP文件变得更加方便。

回到顶部