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 文件。
我正在编写一个 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 文件。