2012-05-03 31 views
29

¿Hay un ejemplo simple de cómo descomprimir un archivo .zip y extraer los archivos en 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.Forma simple de descomprimir un archivo .zip usando zlib

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

+3

Para los lectores que buscan la manera de hacer lo contrario - para crear un archivo zip usando zlib, véase mi respuesta aquí: http://stackoverflow.com/questions/11370908/how-do-i-use-minizip-on-zlib – niemiro

Respuesta

41

zlib maneja el algoritmo de compresión/descompresión deflacta, 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í adjuntar ejemplo quick'n'dirty de LibZIP, con todos los controles de error oitirán:

#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; 
} 
+2

¿Podría proporcionar un ejemplo simple de cómo descomprimir un archivo usando libzip? – judeclarke

+0

No hay problema. Ver la respuesta actualizada. – rodrigo

+0

después de días de lucha con libzip para compilarlo en Windows, resulta que el código de tu publicación no se compila. zip_stat es una función, no es un tipo como usted mencionó – judeclarke

25

Minizip sí tiene programas de ejemplo para demostrar su uso - los archivos se llaman minizip.c y miniunz.c.

Actualización: Tuve unos minutos, por lo que exploté este rápido y escueto ejemplo para usted. 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; 
} 

que construyó y probó con MinGW/MSYS en Windows como esto:

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

Miré ese ejemplo previamente y ese es un gran ejemplo. ¿Hay un ejemplo más simple que podrías proporcionar? – judeclarke

+0

@judeclarke, estoy lejos de mi caja de desarrollo por el día, pero publicaré algo más pequeño/más simple cuando pueda. –

+5

Simplemente necesita tomarse el tiempo para leer los archivos de encabezado y los ejemplos. Primero observe zip.h y descomprima.h para ver cuáles son las funciones que se proporcionan y qué hacen. Luego mira minizip.c y miniunz.c para ver cómo se usan. –

Cuestiones relacionadas