2012-07-23 47 views
5

Tôi có tệp archive.zip chứa hai tệp ".txt" được mã hóa. Tôi muốn giải nén kho lưu trữ để lấy 2 tệp đó.Giải nén tệp zip bằng zlib

Dưới đây là những gì tôi đã làm như vậy cho đến nay:

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"); 

tôi luôn luôn nhận được "lỗi dữ liệu uncompression" và tôi không biết tại sao. Và sau đó tôi muốn biết làm thế nào để lấy 2 tập tin với dữ liệu của tôi không nén.

Trả lời

4

Zlib không phải là thư viện để xử lý tệp .zip. Nó hỗ trợ giải nén các luồng zlib và gzip, cả hai đều hoạt động trên cấp độ của một luồng dữ liệu duy nhất, thay vì định dạng "lưu trữ" như .zip.

Bạn sẽ cần một thư viện khác (ví dụ: libzip; có nhiều loại khác) để mở và thao tác lưu trữ .zip.

+0

Oh thực sự, tôi đã chắc chắn rằng zlib sẽ đối phó với .zip .. dù sao cảm ơn thông tin! :) – user1336204

+0

zlib thực tế có thể giúp xử lý zip và phân phối nguồn đi kèm với mã được đóng góp để xử lý các tệp zip. Xem câu trả lời của tôi. –

+1

Ồ, và libzip sử dụng zlib. –

12

zip là định dạng tệp kết thúc tốt đẹp thông tin tiêu đề và đoạn giới thiệu xung quanh luồng dữ liệu nén để đại diện cho tập hợp các tệp và thư mục. Các luồng dữ liệu nén gần như luôn luôn là deflate data streams, mà thực tế có thể được tạo ra và giải mã bởi zlib. zlib cũng cung cấp chức năng crc32 có thể được sử dụng để tạo và kiểm tra giá trị crc trong thông tin trình bao bọc zip.

Bản thân zlib không tự giải mã và giải mã cấu trúc zip. Bạn có thể viết mã của riêng bạn để làm điều đó bằng cách sử dụng specification (không phải là rất khó làm), hoặc bạn có thể sử dụng các thói quen minizip trong contrib/minizip directory của zlib distribution, cung cấp các chức năng để mở, truy cập và đóng các tệp zip.

+0

Cảm ơn. Tôi đã thêm vào các tiêu đề contrib/minizip và có thể đọc các tập tin từ một zip (trong một ứng dụng đã sử dụng zlib).Tôi chỉ phải viết một số chức năng đơn giản để kết nối các cuộc gọi đến giao diện trong unzip.h –

2

Như đã đề cập, zlib chỉ xử lý nén, nó không lưu trữ. Khi bạn muốn nén hoặc giải nén những gì bạn đang làm là giải nén tệp từ tệp lưu trữ xảy ra ở định dạng zip (có các định dạng khác như rar, 7zip và v.v.)

Nếu bạn muốn tạo nén hoặc giải nén các tệp bạn phải xử lý định dạng zip và minizip là một thư viện đẹp, mạnh mẽ và đã ở đó trong một thời gian khá dài.

Có một đóng góp cho minizip https://github.com/nmoinvaz/minizip với các ví dụ về cách sử dụng nó. Không phải là khó khăn, và bạn có thể kiểm tra các minizip.c và miniunz.c cho mã về cách sử dụng nó. (Minizip sử dụng zlib để nén)

Ngoài ra tôi đã kết thúc xây dựng thư viện kết thúc tốt đẹp và thêm nhiều tính năng đẹp cho nó và giúp dễ sử dụng hơn và hướng đối tượng hơn. Cho phép bạn làm những việc như zip toàn bộ thư mục, luồng, vectơ, v.v. Cũng như làm mọi thứ hoàn toàn trong bộ nhớ.

Repo với các ví dụ ở đây: https://github.com/sebastiandev/zipper

Beta trước khi phát hành: https://github.com/sebastiandev/zipper/releases/

Mã trông giống như sau:

Zipper zipper("ziptest.zip"); 
zipper.add("somefile.txt"); 
zipper.add("myFolder"); 
zipper.close(); 
Các vấn đề liên quan