2017-10-06 180 views
0

我有一個.zip文件來解壓縮包含多個子文件夾。我正在使用zlib.h庫函數來解壓縮.zip文件。如何使用zlib.h庫將.zip文件解壓縮到文件夾中?

#include<stdio.h> 
#include<zlib.h> 
#define MAX_MOI_PATH  200 
#define READ_BLOCK_SIZE 1024*16 

BOOL DCompressFile(char *SourceFILENAME, char *DestinationFILENAME) 
{ 
    char buffer[READ_BLOCK_SIZE]; 
    unsigned long dwBytesRead; 
    unsigned long numberOfBytesWritten; 
    Bool status = false; 
    char cFilename[MAX_MOI_PATH]; 
    int pathIndex=0; 
    char FileMode[4] = "w"; 


    gzFile * FileFd = (gzFile *)gzopen (SourceFILENAME, "rb"); 

    if (FileFd) 
    { 
     FILE* handle = fopen(DestinationFILENAME, "wb"); 

     if(handle != NULL) 
     { 
     status = true; 
     while (status) 
      { 
      dwBytesRead = gzread(FileFd, buffer, READ_BLOCK_SIZE-1); 
      buffer[dwBytesRead] = '\0'; 
      if (dwBytesRead) 
      { 
     status = fwrite(buffer, 1 , sizeof(buffer) , handle); 
     if(!status) 
      status = false; 
     else if (dwBytesRead < READ_BLOCK_SIZE) 
     { 
       break; 
      status = false; 
     }   
      } 
     } 

     fclose(handle); 
     } 
     gzclose (FileFd); 
    } 
    return status; 
} 
int main() 
{ 

    DCompressFile("/home/vivek/zlib_test/1.zip","/home/vivek/zlib_test/1"); 

    return 0; 
} 

問題,此源代碼,它再次創造一個zip文件「1.zip」與相同的內容,而不是解壓縮.zip文件到文件夾。 請幫忙解決這個問題?

+2

的zlib無法解壓ZIP文件這一任務;它解壓'gzip'流。使用libarchive會更好。 –

回答

1

我完成使用libarchive

static int 
copy_data(struct archive *ar, struct archive *aw) 
{ 
    int r; 
    const void *buff; 
    size_t size; 
#if ARCHIVE_VERSION_NUMBER >= 3000000 
    int64_t offset; 
#else 
    off_t offset; 
#endif 

    for (;;) { 
     r = archive_read_data_block(ar, &buff, &size, &offset); 
     if (r == ARCHIVE_EOF) 
      return (ARCHIVE_OK); 
     if (r != ARCHIVE_OK) 
      return (r); 
     r = archive_write_data_block(aw, buff, size, offset); 
     if (r != ARCHIVE_OK) { 
      return (r); 
     } 
    } 
} 

static int 
extract(const char *filename) 
{ 
    struct archive *a; 
    struct archive *ext; 
    struct archive_entry *entry; 
    int flags; 
    int r; 

    //Select which attributes we want to restore. 
    flags = ARCHIVE_EXTRACT_TIME; 
    flags |= ARCHIVE_EXTRACT_PERM; 
    flags |= ARCHIVE_EXTRACT_ACL; 
    flags |= ARCHIVE_EXTRACT_FFLAGS; 

    a = archive_read_new(); 
    archive_read_support_filter_all(a); 
    archive_read_support_format_all(a); 
    ext = archive_write_disk_new(); 
    archive_write_disk_set_options(ext, flags); 
    archive_write_disk_set_standard_lookup(ext); 
    if ((r = archive_read_open_filename(a, filename, 16384))) 
    { 
    printf("File name %s\n",filename); 
    return 1; 
    } 

    for (;;) { 
    r = archive_read_next_header(a, &entry); 
printf("%s \n",archive_entry_pathname(entry)); 
    if (r == ARCHIVE_EOF) 
     break; 
    if (r < ARCHIVE_OK) 
    { 
     fprintf(stderr, "%s\n", archive_error_string(a)); 
     printf("Error1 : %s\n",archive_error_string(a)); 
    if (r < ARCHIVE_WARN) 
     return 1; 
    } 

    r = archive_write_header(ext, entry); 

    if (r < ARCHIVE_OK){ 
     fprintf(stderr, "%s\n", archive_error_string(ext)); 
     printf("Error2 : %s\n",archive_error_string(ext)); 
    } 
    else if (archive_entry_size(entry) > 0) { 

     r = copy_data(a, ext); 

     if (r < ARCHIVE_OK){ 
     fprintf(stderr, "%s\n", archive_error_string(ext)); 
     printf("Error3 : %s\n",archive_error_string(ext)); 
     } 
     if (r < ARCHIVE_WARN) 
     return 1; 
    } 

    r = archive_write_finish_entry(ext); 

    if (r < ARCHIVE_OK){ 
     fprintf(stderr, "%s\n", archive_error_string(ext)); 
     printf("Error4 : %s\n",archive_error_string(ext)); 
    } 
    if (r < ARCHIVE_WARN) 
     return 1; 
    } 
    archive_read_close(a); 
    archive_read_free(a); 
    archive_write_close(ext); 
    archive_write_free(ext); 
    return 0; 
} 

int main() 
{ 
extract("/home/sanjay/zlib_test/FileDownload.zip"); 
return 0; 
}