2012-07-23 20 views
5

Ho un file archive.zip che contiene due file ".txt" criptati. Vorrei decomprimere l'archivio per recuperare quei 2 file.Decomprimere un file zip utilizzando zlib

Ecco che cosa ho fatto finora:

FILE *FileIn = fopen("./archive.zip", "rb"); 
if (FileIn) 
    printf("file opened\n"); 
else 
    printf("unable to open file\n"); 

fseek(FileIn, 0, SEEK_END); 
unsigned long FileInSize = ftell(FileIn); 
printf("size of input compressed file : %u\n", FileInSize); 

void *CompDataBuff = malloc(FileInSize); 
void *UnCompDataBuff = NULL; 

int fd = open ("archive.zip", O_RDONLY); 
CompDataBuff = mmap(NULL, FileInSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 
printf("buffer read : %s\n", (char *)CompDataBuff); 

uLongf UnCompSize = (FileInSize * 11/10 + 12); 
UnCompDataBuff = malloc(UnCompSize); 

int ret_uncp ; 

ret_uncp = uncompress((Bytef*)UnCompDataBuff, &UnCompSize, (const Bytef*)CompDataBuff,FileInSize); 
printf("size of uncompressed data : %u\n", UnCompSize); 

if (ret_uncp == Z_OK){ 
    printf("uncompression ok\n"); 
    printf("uncompressed data : %s\n",(char *)UnCompDataBuff); 
    } 
if (ret_uncp == Z_MEM_ERROR) 
    printf("uncompression memory error\n"); 
if (ret_uncp == Z_BUF_ERROR) 
    printf("uncompression buffer error\n"); 
if (ret_uncp == Z_DATA_ERROR) 
    printf("uncompression data error\n"); 

ottengo sempre "errore nei dati di decompressione" e non so perché. E poi mi piacerebbe sapere come recuperare i 2 file con i miei dati non compressi.

risposta

4

Zlib non è una libreria per la gestione dei file .zip. Supporta la decompressione di stream zlib e gzip, entrambi funzionanti al livello di un singolo flusso di dati, piuttosto che un formato di "archivio" come .zip.

Avresti bisogno di una libreria diversa (per un esempio, libzip, ce ne sono molti altri) per aprire e manipolare gli archivi .zip.

+0

Oh davvero, ero sicuro che sarebbe zlib trattare con zip .. comunque grazie per l'informazione! :) – user1336204

+0

zlib può infatti aiutare con l'elaborazione zip e la distribuzione di origine viene fornita con il codice fornito per elaborare i file zip. Vedi la mia risposta. –

+1

Oh, e libzip usa zlib. –

12

zip è un formato di file che racchiude le informazioni di intestazione e trailer attorno a flussi di dati compressi per rappresentare un insieme di file e directory. I flussi di dati compressi sono quasi sempre deflate data streams, che in realtà possono essere generati e decodificati da zlib. zlib fornisce anche la funzione crc32 che può essere utilizzata per generare e controllare i valori crc nelle informazioni del wrapper zip.

Quello che zlib non fa da solo è decodificare e decostruire la struttura zip. Puoi scrivere il tuo codice per farlo usando lo specification (non molto difficile da fare), oppure puoi usare le routine minizip nello contrib/minizip directory del zlib distribution, che fornisce le funzioni per aprire, accedere e chiudere i file zip.

+0

Grazie. Ho aggiunto le intestazioni contrib/minizip ed è stato in grado di leggere i file da un file zip (in un'applicazione che già utilizzava zlib).Ho appena dovuto scrivere alcune semplici funzioni per racchiudere le chiamate all'interfaccia in unzip.h –

2

Come accennato, zlib gestisce solo la compressione, non archivia. Quando vuoi comprimere o decomprimere ciò che stai facendo è estrarre file da un archivio che si trova in un formato zip (ci sono altri formati come rar, 7zip e così via)

Se vuoi creare zip o decomprimere i file devi gestire il formato zip e minizip è una bella libreria, robusta ed è stata lì per un periodo piuttosto lungo.

C'è un contributo per il minizip https://github.com/nmoinvaz/minizip con esempi su come usarlo. Non è difficile, e puoi controllare minizip.c e miniunz.c per il codice su come usarlo. (Minizip utilizza zlib per la compressione)

Inoltre ho finito per costruire una libreria che avvolge il minizip e aggiunge un sacco di funzioni interessanti e rende più facile l'utilizzo e più orientato agli oggetti. Consente di fare cose come zip intere cartelle, flussi, vettori, ecc. Oltre a fare tutto interamente in memoria.

Repo con esempi qui: https://github.com/sebastiandev/zipper

Beta pre-release: https://github.com/sebastiandev/zipper/releases/

codice simile a:

Zipper zipper("ziptest.zip"); 
zipper.add("somefile.txt"); 
zipper.add("myFolder"); 
zipper.close(); 
Problemi correlati