Zlib Inflate () сбой с ошибкой данных -3 Z

Я пытаюсь распаковать файл, вызвав функцию inflate, но она всегда терпит неудачу с Z_DATA_ERROR, даже когда я использую пример программы с веб-сайта. Я думаю, что, возможно, zip-файл, который у меня есть, не поддерживается. Я прикрепил изображение заголовка zip ниже.

enter image description here

а вот функция, которую я написал для выполнения распаковки. Я читаю сразу весь файл (около 34KB) и передаю его в эту функцию. Примечание. Я попытался передать все zip-файл с заголовком zip, а также пропуск заголовка zip-файла и передача только сжатых данных завершаются ошибкой Z_DATA_ERROR при вызове inflate ().

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;
}

Итак, мой вопрос: тип zip-файла, который я читаю, не поддерживается функцией inflate() ZLib? Или что-то не так с моей функцией CHttpDownloader::unzip ()? Спасибо за любую помощь :)

2 ответов


Inflate () не удалось, потому что он искал заголовки GZip, которых не было. Если вы инициализируете поток с помощью:

ret = inflateInit2(&strm, -MAX_WBITS);

передача отрицательного значения бит окна предотвращает проверку inflate на наличие заголовков gzip или zlib, и распаковка работает должным образом.


файл, который начинается с 50 4B 03 04 - Это zip-файл. Библиотекой zlib не обрабатывает zip файлы напрямую. zlib может помочь с вычислениями сжатия, декомпрессии и crc. Однако вам нужен другой код для обработки формата zip-файла.

Вы можете посмотреть contrib/minizip в дистрибутиве zlib или libzip.