c++ zip zlib unzip

c++ - Manera simple de descomprimir un archivo.zip usando zlib



unzip (2)

Esta pregunta ya tiene una respuesta aquí:

¿Hay un ejemplo simple de cómo descomprimir un archivo .zip y extraer los archivos a un directorio? Actualmente estoy usando zlib, y si bien entiendo que zlib no trata directamente con archivos zip, parece que hay varias cosas adicionales en la biblioteca "contrib" de zlibs. Noté y leí sobre "minizip", y después de leer algunos documentos y mirar algunos de los códigos, no veo un ejemplo simple de cómo descomprimir un archivo .zip y extraer los archivos a un directorio.

Me gustaría encontrar una plataforma independiente para hacerlo, pero si eso no es posible, entonces necesito encontrar una forma de Windows y Mac.


Minizip tiene un ejemplo de programas para demostrar su uso: los archivos se llaman minizip.c y miniunz.c.

Actualización: Tenía unos minutos, así que inventé este ejemplo rápido y escueto para ti. Es muy maloliente C, y no lo usaría sin grandes mejoras. Espero que sea suficiente para que puedas continuar por el momento.

// uzip.c - Simple example of using the minizip API. // Do not use this code as is! It is educational only, and probably // riddled with errors and leaks! #include <stdio.h> #include <string.h> #include "unzip.h" #define dir_delimter ''/'' #define MAX_FILENAME 512 #define READ_SIZE 8192 int main( int argc, char **argv ) { if ( argc < 2 ) { printf( "usage:/n%s {file to unzip}/n", argv[ 0 ] ); return -1; } // Open the zip file unzFile *zipfile = unzOpen( argv[ 1 ] ); if ( zipfile == NULL ) { printf( "%s: not found/n" ); return -1; } // Get info about the zip file unz_global_info global_info; if ( unzGetGlobalInfo( zipfile, &global_info ) != UNZ_OK ) { printf( "could not read file global info/n" ); unzClose( zipfile ); return -1; } // Buffer to hold data read from the zip file. char read_buffer[ READ_SIZE ]; // Loop to extract all files uLong i; for ( i = 0; i < global_info.number_entry; ++i ) { // Get info about current file. unz_file_info file_info; char filename[ MAX_FILENAME ]; if ( unzGetCurrentFileInfo( zipfile, &file_info, filename, MAX_FILENAME, NULL, 0, NULL, 0 ) != UNZ_OK ) { printf( "could not read file info/n" ); unzClose( zipfile ); return -1; } // Check if this entry is a directory or file. const size_t filename_length = strlen( filename ); if ( filename[ filename_length-1 ] == dir_delimter ) { // Entry is a directory, so create it. printf( "dir:%s/n", filename ); mkdir( filename ); } else { // Entry is a file, so extract it. printf( "file:%s/n", filename ); if ( unzOpenCurrentFile( zipfile ) != UNZ_OK ) { printf( "could not open file/n" ); unzClose( zipfile ); return -1; } // Open a file to write out the data. FILE *out = fopen( filename, "wb" ); if ( out == NULL ) { printf( "could not open destination file/n" ); unzCloseCurrentFile( zipfile ); unzClose( zipfile ); return -1; } int error = UNZ_OK; do { error = unzReadCurrentFile( zipfile, read_buffer, READ_SIZE ); if ( error < 0 ) { printf( "error %d/n", error ); unzCloseCurrentFile( zipfile ); unzClose( zipfile ); return -1; } // Write data to file. if ( error > 0 ) { fwrite( read_buffer, error, 1, out ); // You should check return of fwrite... } } while ( error > 0 ); fclose( out ); } unzCloseCurrentFile( zipfile ); // Go the the next entry listed in the zip file. if ( ( i+1 ) < global_info.number_entry ) { if ( unzGoToNextFile( zipfile ) != UNZ_OK ) { printf( "cound not read next file/n" ); unzClose( zipfile ); return -1; } } } unzClose( zipfile ); return 0; }

Lo construí y probé con MinGW / MSYS en Windows de esta manera:

contrib/minizip/$ gcc -I../.. -o unzip uzip.c unzip.c ioapi.c ../../libz.a contrib/minizip/$ ./unzip.exe /j/zlib-125.zip


zlib maneja el algoritmo de compresión / descompresión de desinflado , pero hay más que eso en un archivo ZIP.

Puedes probar libzip . Es gratis, portátil y fácil de usar.

ACTUALIZACIÓN: Aquí adjunto quick''n''dirty ejemplo de libzip, con todos los controles de error ommited:

#include <zip.h> int main() { //Open the ZIP archive int err = 0; zip *z = zip_open("foo.zip", 0, &err); //Search for the file of given name const char *name = "file.txt"; struct zip_stat st; zip_stat_init(&st); zip_stat(z, name, 0, &st); //Alloc memory for its uncompressed contents char *contents = new char[st.size]; //Read the compressed file zip_file *f = zip_fopen(z, name, 0); zip_fread(f, contents, st.size); zip_fclose(f); //And close the archive zip_close(z); //Do something with the contents //delete allocated memory delete[] contents; }