Biblioteca zip para Rust: guía completa para trabajar con archivos ZIP
En el desarrollo moderno con Rust, trabajar con archivos es una tarea muy demandada. Ya sea para empaquetar registros, descomprimir configuraciones o crear copias de seguridad, la biblioteca estándar zip (crate zip) es la solución de facto para leer y escribir archivos ZIP. En este artículo, analizaremos en detalle cómo instalar la biblioteca, crear un archivo, extraer archivos y también veremos técnicas avanzadas: trabajo con contraseñas, flujos y grandes volúmenes de datos.
Instalación y configuración
Agregue la dependencia en Cargo.toml:
[dependencies]zip = "2.1"Luego, importe los módulos necesarios en el código:
use std::fs::File;use std::io::{Read, Write, BufReader, BufWriter};use zip::ZipWriter;use zip::write::FileOptions;use zip::read::ZipArchive;Creación de un archivo ZIP
Para crear un nuevo archivo se utiliza ZipWriter. Veamos un ejemplo básico: empaquetaremos dos archivos de texto:
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);
// Agregamos el primer archivo zip.start_file("hello.txt", FileOptions::default())?; zip.write_all(b"Hello, Rust archive!")?;
// Agregamos el segundo archivo con compresión 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(())}Importante: el método start_file abre un nuevo archivo dentro del archivo ZIP. Las opciones permiten definir el método de compresión (por defecto Stored — sin compresión, Deflated — compresión ZIP estándar).
Lectura y extracción del archivo
Para la lectura se utiliza ZipArchive. A continuación, una función que lista los archivos y los extrae en el directorio actual:
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!("Extrayendo: {}", name);
// Creamos el archivo en el disco let mut output = File::create(&name)?; std::io::copy(&mut entry, &mut output)?; } Ok(())}El método by_index devuelve un iterador sobre las entradas. Si necesita acceso por nombre, use by_name("path/to/file.txt"). Tenga en cuenta: los nombres en ZIP pueden contener rutas con el separador / — esto es normal para la multiplataforma.
Trabajo con contraseñas (cifrado)
La biblioteca zip admite cifrado basado en contraseña mediante el algoritmo AES (por defecto AES-256). Para crear un archivo cifrado:
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(())}Para leer un archivo cifrado, pase la contraseña al método by_index_decrypt o by_n