ZLib Inflate()失败,带有-3 Z_DATA_ERROR

Meg*_*gan 8 c++ zlib unzip

我试图通过调用inflate函数来解压缩文件,但是即使我使用网站上的示例程序,它总是会失败Z_DATA_ERROR.我想也许我的zip文件可能不受支持.我附上了下面的拉链头图片.

在此输入图像描述

这是我为执行解压缩而编写的函数.我立刻读了整个文件(大约34KB)并将其传递给这个函数.注意我已经尝试使用zip标头传递整个zip文件以及跳过zip文件头,并且只有在调用inflate()时,传递压缩数据才会失败,并且Z_DATA_ERROR失败.

int CHttpDownloader::unzip(unsigned char * pDest, unsigned long * ulDestLen, unsigned char *  pSource, int iSourceLen)
{
int ret = 0;
unsigned int uiUncompressedBytes = 0; // Number of uncompressed bytes returned from inflate() function
unsigned char * pPositionDestBuffer = pDest; // Current position in dest buffer
unsigned char * pLastSource = &pSource[iSourceLen]; // Last position in source buffer
z_stream strm;

// Skip over local file header
SLocalFileHeader * header = (SLocalFileHeader *) pSource;
pSource += sizeof(SLocalFileHeader) + header->sFileNameLen + header->sExtraFieldLen;


// We should now be at the beginning of the stream data
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, 16+MAX_WBITS);
if (ret != Z_OK)
{
return -1;
}

// Uncompress the data
strm.avail_in = header->iCompressedSize; //iSourceLen;
strm.next_in = pSource;

do {
strm.avail_out = *ulDestLen;
strm.next_out = pPositionDestBuffer;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;     /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return -2;
}
uiUncompressedBytes = *ulDestLen - strm.avail_out;
*ulDestLen -= uiUncompressedBytes; // ulDestSize holds number of free/empty bytes in buffer
pPositionDestBuffer += uiUncompressedBytes;
} while (strm.avail_out == 0);

// Close the decompression stream
inflateEnd(&strm);
ASSERT(ret == Z_STREAM_END);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,我正在阅读的zip文件类型是否不受ZLib的inflate()函数支持?或者我的CHttpDownloader :: unzip()函数有问题吗?谢谢你的帮助 :)

Meg*_*gan 18

Inflate()失败了,因为它正在寻找不存在的GZip标头.如果使用以下内容初始化流:

ret = inflateInit2(&strm, -MAX_WBITS);
Run Code Online (Sandbox Code Playgroud)

传递负窗口位值可防止膨胀检查gzip或zlib标头并解压缩按预期工作.

  • 哇这有多疯狂?文档真的根本没有给出任何线索。应该是 zlib 的常见问题解答 IMO 的一部分 (2认同)

Mar*_*ler 5

该文件50 4B 03 04以zip文件开头.zlib库不直接处理zip文件.zlib可以帮助进行压缩,解压缩和crc计算.但是,您需要其他代码来处理zip文件格式.

您可以contrib/minizip在zlib发行版libzip中查看.