Working with ZIP Archives in Rust: The zip Library for Creating and Extracting Archives

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

The zip Library for Working with Archives in Rust



In modern Rust development, there is often a need to package data into ZIP archives or extract it from them. Whether it's creating backups, distributing software, or processing user files — the zip library is the standard solution for this task. It provides a convenient API for reading, writing, and modifying ZIP archives, supporting both streaming and in-memory operations.



Installation and Setup



To get started, add the dependency to your Cargo.toml:



[dependencies]zip = "2.1"


You may also need the std::io crate for working with data streams, which is already part of the Rust standard library.



Creating a New ZIP Archive



Let's look at a simple example — creating an archive with a single text file. This is done using ZipWriter, which wraps any type implementing Write:



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

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

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

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


Note the start_file method — it begins writing a new file inside the archive. You can pass it compression options, modification date, and other parameters.



Reading and Extracting Files



To read an archive, use ZipArchive. It allows you to iterate over all entries and extract their contents:



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

fn main() -> zip::result::ZipResult<()> { let file = File::open("example.zip")?; let mut archive = ZipArchive::new(file)?;

for i in 0..archive.len() { let mut entry = archive.by_index(i)?; let name = entry.name().to_string(); let mut content = String::new(); entry.read_to_string(&mut content)?; println!("{}: {}", name, content); } Ok(())}


The by_index method returns a specific entry by index. Searching by name is also available via by_name, but keep in mind — names in ZIP can be in different encodings.



Adding Files to an Existing Archive



The zip library also supports adding new files to an already created archive. This is done using the raw_copy_file method or by opening the archive in append mode:



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

fn append_to_zip() -> zip::result::ZipResult<()> { let file = File::options() .read(true) .write(true) .open("example.zip")?; let mut zip = ZipWriter::new_append(file)?;

zip.start_file("new_file.txt", FileOptions::default())?; zip.write_all(b"Added later!")?;

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


Important: to add a file, the archive must be opened with read and write permissions, and the file itself must not be corrupted.



Working with Different Compression Types



By default, the library uses the Deflated method (standard ZIP compression). You can change it to Stored (no compression) or other methods by passing the appropriate options:



use zip::CompressionMethod;use zip::write::FileOptions;

let options = FileOptions::default() .compression_method(CompressionMethod::Stored);// orlet options = FileOptions::default() .compression_method(CompressionMethod::Deflated);


If you need maximum compression, specify the level:



<                    

Recommendations