Trabajo con archivos ZIP en C++: reseña de bibliotecas y ejemplos prácticos
La archivación de datos es una de las tareas clave en el desarrollo de software. En C++ no hay soporte integrado para el formato ZIP, sin embargo, existen varias bibliotecas maduras y probadas que permiten empaquetar, descomprimir y modificar archivos ZIP fácilmente. En este artículo revisaremos las herramientas principales: zlib, minizip y libzip, y presentaremos ejemplos prácticos de código.
1. Conceptos básicos del trabajo con ZIP en C++
ZIP es un formato de compresión sin pérdida que soporta varios algoritmos (Deflate, BZip2, LZMA). Para trabajar con él en C++ se suelen usar tres enfoques:
- Trabajo directo con zlib — compresión/descompresión de bajo nivel de flujos de datos, pero sin soporte para la estructura del archivo ZIP.
- minizip — una capa sobre zlib que proporciona funciones para crear y leer archivos ZIP.
- libzip — una biblioteca completa con soporte para editar, eliminar y agregar archivos en archivos existentes.
2. Biblioteca zlib
zlib es una biblioteca de compresión fundamental sobre la que se construyen muchas soluciones ZIP. Proporciona las funciones compress() y uncompress() para trabajar con datos sin procesar.
Ejemplo: compresión de una cadena con zlib
#include <iostream>#include <string>#include <zlib.h>
int main() { std::string input = "¡Ejemplo de texto para comprimir en C++!"; uLong srcLen = input.size(); uLong destLen = compressBound(srcLen); char* compressed = new char[destLen]; if (compress((Bytef*)compressed, &destLen, (const Bytef*)input.data(), srcLen) == Z_OK) { std::cout << "Comprimido: " << srcLen << " -> " << destLen << " bytes"; } delete[] compressed; return 0;}Nota: Para trabajar con zlib es necesario incluir el archivo de cabecera zlib.h y enlazar con la biblioteca -lz.
3. Biblioteca minizip
minizip es un envoltorio ligero sobre zlib que permite crear y extraer archivos ZIP. Se distribuye como parte de las fuentes de zlib (carpeta contrib/minizip).
Ejemplo: creación de un archivo ZIP con un solo archivo
#include <iostream>#include <zip.h> // minizip
int main() { zipFile zf = zipOpen("example.zip", APPEND_STATUS_CREATE); if (!zf) { std::cerr << "Error al crear el archivo"; return 1; } zip_fileinfo info = {0}; const char* filename = "test.txt"; const char* content = "¡Hola desde minizip!"; if (zipOpenNewFileInZip(zf, filename, &info, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) == ZIP_OK) { zipWriteInFileInZip(zf, content, strlen(content)); zipCloseFileInZip(zf); } zipClose(zf, nullptr); std::cout << "Archivo creado: example.zip"; return 0;}Ejemplo: extracción de todos los archivos de un ZIP
#include <iostream>#include <unzip.h>
int main() { unzFile uf = unzOpen("example.zip"); if (!uf) { std::cerr << "No se pudo abrir el archivo"; return 1; } unz_global_info global_info; unzGetGlobalInfo(uf, &global_info); for (uLong i = 0; i < global_info.number_entry; ++i) { char filename[256]; unz_file_info file_info; unzGetCurrentFileInfo(uf, &file_info, filename, sizeof(filename), nullptr, 0, nullptr, 0); if (unzOpenCurrentFile(uf) == UNZ_OK) { c