Trabalhando com arquivos ZIP em Rust usando a biblioteca zip
Ao desenvolver em Rust, frequentemente surge a necessidade de compactar arquivos em arquivos ZIP ou extrair dados deles. Isso pode ser necessário para distribuição de software, criação de backups, processamento de arquivos enviados por usuários ou montagem de pacotes. A biblioteca padrão do Rust não inclui ferramentas integradas para trabalhar com ZIP, no entanto, o ecossistema oferece uma biblioteca poderosa e conveniente: zip.
Neste artigo, vamos detalhar como usar a biblioteca zip para criar, ler e extrair arquivos ZIP. Você aprenderá como instalar a biblioteca, trabalhar com arquivos e diretórios, tratar erros e gerenciar a compressão.
Instalação da biblioteca zip
Para começar, adicione a dependência ao arquivo Cargo.toml do seu projeto:
[dependencies]zip = "2.2"A biblioteca é ativamente mantida e utiliza recursos modernos do Rust. Após adicionar a dependência, você pode importá-la no código:
use zip::ZipWriter;use zip::read::ZipArchive;use std::io::{Read, Write, BufWriter, BufReader};use std::fs::{self, File};Criação de um arquivo ZIP
A criação de um arquivo consiste em várias etapas: abrir o arquivo para escrita, inicializar o ZipWriter, adicionar arquivos e finalizar a escrita. Vejamos um exemplo que compacta um único arquivo de texto:
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(())}Aqui nós:
- Criamos o arquivo
example.zipno diretório atual. - Inicializamos o
ZipWriter. - Configuramos os parâmetros do arquivo: método de compressão
Deflated(compressão padrão) e permissões de acesso. - Adicionamos o arquivo
hello.txte escrevemos seu conteúdo. - Finalizamos a escrita com a chamada
finish().
Para adicionar vários arquivos ou um diretório inteiro, use um loop pelos arquivos na pasta:
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(())}Observação: para percorrer diretórios recursivamente, é conveniente usar a crate walkdir, mas ela precisa ser adicionada separadamente.
Leitura e extração de um arquivo ZIP
Para ler o arquivo, usa-se ZipArchive. Abaixo está um exemplo que lista os arquivos no arquivo ZIP e os extrai para uma pasta especificada:
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!("Extraindo: {}", entry_name);
// Criamos o caminho completo para o arquivo let output_path = format!("{}/{}", output_dir, entry_nam Também na biblioteca
Geração de Relatórios PDF em Kotlin: iText, Apache PDFBox, OpenPDF
Biblioteca WebSocket Kotlin: ktor-client-websockets para tempo real
SDK OpenAI para JavaScript (Node.js): guia completo com exemplos
Pistache para C++: guia completo com exemplos práticos
Trabalho com datas em Swift (iOS/macOS): bibliotecas e frameworks