Biblioteca zip para trabalhar com arquivos em Rust
No desenvolvimento moderno em Rust, frequentemente surge a necessidade de empacotar dados em arquivos ZIP ou extraí-los deles. Seja para criar backups, distribuir software ou processar arquivos de usuários — a biblioteca zip é a solução padrão para essa tarefa. Ela fornece uma API conveniente para ler, escrever e modificar arquivos ZIP, suportando tanto processamento em fluxo quanto trabalho em memória.
Instalação e configuração
Para começar, adicione a dependência ao seu Cargo.toml:
[dependencies]zip = "2.1"Também pode ser necessário o crate std::io para trabalhar com fluxos de dados, que já faz parte da biblioteca padrão do Rust.
Criação de um novo arquivo ZIP
Vamos considerar um exemplo simples — criar um arquivo com um único arquivo de texto. Para isso, usa-se ZipWriter, que envolve qualquer tipo que implemente 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(())}Observe o método start_file — ele inicia a escrita de um novo arquivo dentro do arquivo ZIP. Você pode passar opções de compressão, data de modificação e outros parâmetros.
Leitura e extração de arquivos
Para ler o arquivo, usa-se ZipArchive. Ele permite iterar sobre todas as entradas e extrair seu conteúdo:
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(())}O método by_index retorna uma entrada específica pelo índice. Também é possível buscar pelo nome usando by_name, mas lembre-se — os nomes em ZIP podem estar em diferentes codificações.
Adicionando arquivos a um arquivo existente
A biblioteca zip também suporta adicionar novos arquivos a um arquivo já criado. Isso é feito com o método raw_copy_file ou abrindo o arquivo no modo de adição:
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(())}Importante: para adicionar um arquivo, o arquivo ZIP deve ser aberto com permissões de leitura e escrita, e o próprio arquivo não deve estar corrompido.
Trabalhando com diferentes tipos de compressão
Por padrão, a biblioteca usa o método Deflated (compressão padrão ZIP). Você pode alterá-lo para Stored (sem compressão) ou outros métodos, passando as opções correspondentes:
use zip::CompressionMethod;use zip::write::FileOptions;
let options = FileOptions::default() .compression_method(CompressionMethod::Stored);// oulet options = FileOptions::default() .compression_method(CompressionMethod::Deflated);Se você precisar de compressão máxima, especifique o nível:
<