zlib error -3 while decompressing archive: 不正确的数据检查

zlib error -3 while decompressing archive: Incorrect data check

我正在编写一个 C++ 库,它也可以解压缩 zlib 文件。对于所有文件,对 gzread() 的最后一次调用(或最后一次调用中的至少一次)给出了错误 -3 (Z_DATA_ERROR) 以及消息“不正确的数据检查”。由于我没有自己创建文件,所以我不完全确定哪里出了问题。

我找到了 this 个答案,如果我找到了

gzip -dc < myfile.gz > myfile.decomp
gzip: invalid compressed data--crc error

在命令行上 myfile.decomp 的内容似乎是正确的。然而,在这种情况下仍然打印出 crc 错误,这可能是也可能不是同一个问题。我的代码粘贴在下面,应该很简单,但我不确定如何在代码中获得与上面命令行相同的行为。

如何在代码中实现与命令行相同的行为?

std::vector<char> decompress(const std::string &path)
{
    gzFile inFileZ = gzopen(path.c_str(), "rb");
    if (inFileZ == NULL)
    {
        printf("Error: gzopen() failed for file %s.\n", path.c_str());
        return {};
    }

    constexpr size_t bufSize = 8192;
    char unzipBuffer[bufSize];
    int unzippedBytes = bufSize;

    std::vector<char> unzippedData;
    unzippedData.reserve(1048576); // 1 MiB is enough in most cases.

    while (unzippedBytes == bufSize)
    {
        unzippedBytes = gzread(inFileZ, unzipBuffer, bufSize);

        if (unzippedBytes == -1)
        {
            // Here the error is -3 / "incorrect data check" for (one of) the last block(s)
            // in the file. The bytes can be correctly decompressed, as demonstrated on the
            // command line, but how can this be achieved in code?
            int errnum;
            const char *err = gzerror(inFileZ, &errnum);
            printf(err, "%s\n");
            break;
        }

        if (unzippedBytes > 0)
        {
            unzippedData.insert(unzippedData.end(), unzipBuffer, unzipBuffer + unzippedBytes);
        }
    }

    gzclose(inFileZ);
    return unzippedData;
}

首先,CRC 的全部意义在于检测损坏的数据。如果 CRC 错误,那么您应该返回到此文件的来源并让数据 而不是 损坏。如果CRC错误,则丢弃输入并报错。

您不清楚您试图重现的“行为”,但如果您试图从损坏的 gzip 文件中恢复尽可能多的数据,那么您将需要使用 zlib 的 inflate 函数来解压缩文件。 int ret = inflateInit2(&strm, 31); 将初始化 zlib 流以处理 gzip 文件。