2012-05-03 20 views
29

C'è un semplice esempio di come decomprimere un file .zip ed estrarre i file in una directory? Attualmente sto usando zlib e, mentre capisco che zlib non gestisce direttamente i file zip, sembra che ci siano molte altre cose nella libreria "contrib" di zlibs. Ho notato e letto su "minizip", e dopo aver letto alcuni documenti e guardando un po 'del codice, non vedo un semplice esempio di come decomprimere un file .zip ed estrarre i file in una directory.Un modo semplice per decomprimere un file .zip usando zlib

Mi piacerebbe trovare una piattaforma indipendente per farlo, ma se ciò non è possibile, ho bisogno di trovare un modo per Windows e Mac.

+3

Per i lettori alla ricerca di come fare il contrario - per creare un file zip utilizzando zlib, vedere la mia risposta qui: http://stackoverflow.com/questions/11370908/how-do-i-use-minizip-on-zlib – niemiro

risposta

41

zlib gestisce l'algoritmo di compressione/decompressione deflate , ma c'è di più in un file ZIP.

Si può provare libzip. È gratuito, portatile e facile da usare.

UPDATE: Qui ho allegare esempio quick'n'dirty di libzip, con tutti i controlli di errore 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; 
} 
+2

Potresti fornire un semplice esempio di come decomprimere un file usando libzip? – judeclarke

+0

Nessun problema. Vedi la risposta aggiornata. – rodrigo

+0

dopo giorni di wrestling con libzip per farlo compilare su Windows, si scopre che il codice nel tuo post non viene compilato. zip_stat è una funzione, non un tipo come hai detto – judeclarke

25

Minizip ha un esempio i programmi per dimostrare il suo utilizzo - i file sono chiamati minizip.c e miniunz.c.

Aggiornamento: ho avuto qualche minuto così ho montato questo esempio veloce e spoglio per te. È molto puzzolente C, e non lo userei senza grandi miglioramenti. Spero che sia abbastanza per farti andare per ora.

// 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; 
} 

ho costruito e testato con MinGW/MSYS su Windows in questo modo:

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

Ho esaminato questo esempio in precedenza e questo è un esempio enorme. c'è un esempio più semplice che potresti fornire? – judeclarke

+0

@judeclarke, sono lontano dal mio box di sviluppo per il giorno, ma pubblicherò qualcosa di più piccolo/semplice quando posso! –

+5

Devi semplicemente prendere il tempo per leggere i file di intestazione e gli esempi. Per prima cosa guardate a zip.h e unzip.h per vedere quali sono le funzioni fornite e cosa fanno. Quindi guarda minizip.c e miniunz.c per vedere come vengono utilizzati. –

Problemi correlati