ZLib Inflate()失败,-3 Z_DATA_ERROR

问题描述 投票:8回答:2

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

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS8wNXUydS5wbmcifQ==” alt =“在此处输入图像描述”>

这是我编写的用于执行解压缩的功能。我一次读取了整个文件(大约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;
}

所以我的问题是,ZLib的inflate()函数是否不支持我正在读取的zip文件类型?还是我的CHttpDownloader :: unzip()函数有问题?感谢您的帮助:)

c++ zlib unzip
2个回答
19
投票

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

ret = inflateInit2(&strm, -MAX_WBITS);

传递负的窗口位值可防止膨胀检查gzip或zlib标头,并且按预期进行解压缩。


5
投票

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

您可以查看contrib/minizip in the zlib distributioncontrib/minizip

© www.soinside.com 2019 - 2024. All rights reserved.