使用zlib解压缩zip文件

时间:2012-07-23 11:49:37

标签: c zlib unzip compression

我有一个archive.zip,其中包含两个加密的“.txt”文件。我想解压缩存档以检索这2个文件。

这是我到目前为止所做的:

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

我总是得到“解压缩数据错误”,我不知道为什么。然后我想知道如何使用未压缩的数据检索2个文件。

3 个答案:

答案 0 :(得分:13)

zip是一种文件格式,它包含压缩数据流周围的标题和尾部信息,以表示一组文件和目录。压缩数据流几乎总是deflate data streams,实际上可以由zlib生成和解码。 zlib还提供crc32函数,可用于生成和检查zip包装器信息中的crc值。

zlib本身不做的是解码和解构zip结构。您可以使用specification编写自己的代码来执行此操作(不是很难),或者您可以使用contrib/minizip directoryzlib distribution中的minizip例程,它提供了函数打开,访问和关闭zip文件。

答案 1 :(得分:6)

Zlib不是用于处理.zip文件的库。它支持解压缩zlib和gzip流,这两个流都在单个数据流的层面上工作,而不是像.zip那样的“归档”格式。

您需要一个不同的库(例如,libzip;还有许多其他库)来打开和操作.zip档案。

答案 2 :(得分:2)

如上所述,zlib只处理压缩​​,它不归档。当你想要压缩或解压缩你正在做的是从档案中提取文件时恰好是zip格式(还有其他格式,如rar,7zip等)

如果你想创建拉链或解压缩文件,你必须处理zip格式,minizip是一个很好的库,非常强大并且已经存在了很长时间。

minizip https://github.com/nmoinvaz/minizip有一个贡献,其中有关于如何使用它的示例。不是那么难,你可以检查minizip.c和miniunz.c以获取有关如何使用它的代码。 (Minizip使用zlib进行压缩)

此外,我最终构建了一个包装minizip的库,并为其添加了许多不错的功能,使其更易于使用和更面向对象。让你做一些事情,如压缩整个文件夹,流,矢量等。以及完全在内存中完成所有事情。

回复示例:https://github.com/sebastiandev/zipper

Beta预发布:https://github.com/sebastiandev/zipper/releases/

代码类似于:

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