Работа с ZIP/архивами в Rust: библиотека zip и полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Библиотека zip для Rust: полное руководство по работе с ZIP-архивами

В современной разработке на Rust работа с архивами — востребованная задача. Будь то упаковка логов, распаковка конфигураций или создание бэкапов — стандартная библиотека zip (crate zip) является де-факто решением для чтения и записи ZIP-файлов. В этой статье мы подробно разберём, как установить библиотеку, создать архив, извлечь файлы, а также рассмотрим продвинутые техники: работу с паролями, потоками и большими данными.

Установка и подключение

Добавьте зависимость в Cargo.toml:

[dependencies]
zip = "2.1"

После этого импортируйте необходимые модули в коде:

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

Создание ZIP-архива

Для создания нового архива используется ZipWriter. Рассмотрим базовый пример — упакуем два текстовых файла:

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

fn create_archive() -> 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 archive!")?;

    // Добавляем второй файл с компрессией
    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Deflated)
        .unix_permissions(0o755);
    zip.start_file("data/config.json", options)?;
    zip.write_all(b"{\"version\": 1}")?;

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

Важно: метод start_file открывает новый файл внутри архива. Опции позволяют задать метод сжатия (по умолчанию Stored — без сжатия, Deflated — стандартное сжатие ZIP).

Чтение и извлечение архива

Для чтения используется ZipArchive. Ниже — функция, которая выводит список файлов и извлекает их в текущую директорию:

use std::fs::File;
use std::io::{Read, BufReader};
use zip::ZipArchive;

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

    for i in 0..archive.len() {
        let mut entry = archive.by_index(i)?;
        let name = entry.name().to_string();
        println!("Извлекаем: {}", name);

        // Создаём файл на диске
        let mut output = File::create(&name)?;
        std::io::copy(&mut entry, &mut output)?;
    }
    Ok(())
}

Метод by_index возвращает итератор по записям. Если нужен доступ по имени — используйте by_name("path/to/file.txt"). Обратите внимание: имена в ZIP могут содержать пути с разделителем / — это нормально для кросс-платформенности.

Работа с паролями (шифрование)

Библиотека zip поддерживает шифрование на основе пароля через алгоритм AES (по умолчанию AES-256). Для создания зашифрованного архива:

use zip::ZipWriter;
use zip::write::FileOptions;
use zip::AesMode;

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

    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Deflated)
        .with_aes_encryption(AesMode::Aes256, "my_strong_password");

    zip.start_file("secret.txt", options)?;
    zip.write_all(b"Top secret data")?;
    zip.finish()?;
    Ok(())
}

Для чтения зашифрованного архива передайте пароль в метод by_index_decrypt или by_name_decrypt:

let mut entry = archive.by_name_decrypt("secret.txt", "my_strong_password")?;
let mut content = String::new();
entry.read_to_string(&mut content)?;
println!("Содержимое: {}", content);

Важно: шифрование доступно только в версии zip 2.x и требует включения фичи aes-crypto в Cargo.toml:

zip = { version                    

Рекомендаций