在 Rust 中处理 ZIP 压缩包:zip 库与完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

使用 zip 库在 Rust 中处理 ZIP 压缩包



在使用 Rust 进行开发时,经常需要将文件打包成 ZIP 压缩包或从中提取数据。这可能是为了分发软件、创建备份、处理用户上传的压缩包或构建包。Rust 标准库不包含处理 ZIP 的内置工具,但生态系统提供了一个强大且方便的库 zip。



在本文中,我们将详细介绍如何使用 zip 库创建、读取和提取 ZIP 压缩包。您将了解如何安装该库、处理文件和目录、处理错误以及管理压缩。



安装 zip 库



首先,将依赖项添加到项目的 Cargo.toml 文件中:



[dependencies]zip = "2.2"


该库受到积极维护,并利用了 Rust 的现代特性。添加依赖项后,您可以在代码中导入它:



use zip::ZipWriter;use zip::read::ZipArchive;use std::io::{Read, Write, BufWriter, BufReader};use std::fs::{self, File};


创建 ZIP 压缩包



创建压缩包包含几个步骤:打开文件进行写入,初始化 ZipWriter,添加文件,然后完成写入。考虑一个打包单个文本文件的示例:



use std::fs::File;use zip::ZipWriter;use zip::write::FileOptions;use std::io::Write;

fn create_archive() -> zip::result::ZipResult<()> { let file = File::create("example.zip")?; let mut zip = ZipWriter::new(file);

let options = FileOptions::default() .compression_method(zip::CompressionMethod::Deflated) .unix_permissions(0o755);

zip.start_file("hello.txt", options)?; zip.write_all(b"Hello, Rust ZIP!")?;

zip.finish()?; Ok(())}


在这里,我们:

  • 在当前目录中创建文件 example.zip。
  • 初始化 ZipWriter。
  • 配置文件参数:压缩方法 Deflated(标准压缩)和权限。
  • 添加文件 hello.txt 并写入内容。
  • 通过调用 finish() 完成写入。


要添加多个文件或整个目录,请使用循环遍历文件夹中的文件:



fn add_directory(zip: &mut ZipWriter<File>, dir_path: &str) -> zip::result::ZipResult<()> {    for entry in walkdir::WalkDir::new(dir_path) {        let entry = entry?;        let path = entry.path();        if path.is_file() {            let name = path.strip_prefix(dir_path).unwrap().to_str().unwrap();            zip.start_file(name, FileOptions::default())?;            let mut f = File::open(path)?;            std::io::copy(&mut f, zip)?;        }    }    Ok(())}


请注意:为了递归遍历目录,使用 crate walkdir 会很方便,但需要单独添加。



读取和提取 ZIP 压缩包



要读取压缩包,请使用 ZipArchive。下面是一个示例,列出压缩包中的文件并将其提取到指定文件夹:



use zip::ZipArchive;use std::io::Read;

fn extract_archive(archive_path: &str, output_dir: &str) -> zip::result::ZipResult<()> { let file = File::open(archive_path)?; let mut archive = ZipArchive::new(file)?;

for i in 0..archive.len() { let mut entry = archive.by_index(i)?; let entry_name = entry.name().to_string(); println!("正在提取: {}", entry_name);

// 创建文件的完整路径 let output_path = format!("{}/{}", output_dir, entry_nam

推荐