ZLib GZIP Returning Z_BUF_ERROR(-5)

ZLib GZIP Returning Z_BUF_ERROR(-5)

本文关键字:ERROR BUF Returning ZLib GZIP      更新时间:2023-10-16

我正在使用 zlib 库(从 src 编译(来压缩/膨胀 gzip/zlib/raw bytes。我创建了一个用于解压缩和压缩的包装类(压缩器/解压缩器(。我还创建了几个测试用例(GZIP,ZLib,Raw,Auto-Detect(。测试通过了Zlib/Raw/Auto-Detect(Zlib(,但GZip(15u | 16u的窗口位(则不合格。

这是我的压缩功能。

std::vector<char> out(zlib->avail_in + 8);
deflateInit2(zlib.get(), Z_DEFAULT_COMPRESSION, Z_DEFLATED, static_cast<int32_t>(mode), 8, Z_DEFAULT_STRATEGY);
zlib->avail_out = out.size();
zlib->next_out = reinterpret_cast<Bytef*>(out.data());
deflate(zlib.get(), Z_FINISH);
out.resize(zlib->total_out + 3);
deflateEnd(zlib.get());
return std::move(out);

这是解压

uIntf multiplier = 2;
uIntf currentSize = zlib->avail_in * (multiplier++) * 1000 /* Just to make sure enough output space(will implement loop) */;
std::vector<char> out(currentSize);
inflateInit2(zlib.get(), static_cast<int>(mode));
zlib->avail_out = out.size();
zlib->next_out = reinterpret_cast<Bytef*>(out.data());
inflate(zlib.get(), Z_FINISH);
out.resize(zlib->total_out);
inflateEnd(zlib.get());
return std::move(out);

输入设置在不同的函数(正在调用(中,如下所示。(调用压缩/解压缩时不会删除 char*(

zlib->next_in = reinterpret_cast<Bytef*>(bytes);
zlib->avail_in = static_cast<uIntf>(length);

我还有一个模式枚举

enum class Mode : int32_t {
AUTO = 15u | 32u, // Never used on compress
GZIP = 15u | 16u,
ZLIB = 15,
RAW = -15
};

注意:模式AUTO(与 zlib 配对(、ZLibRAW的测试用例工作。GZip 未通过测试用例。(测试用例只是一个简单的字母数字字符数组(。

我还调试了 gzip 解压缩的输出(失败后(,输出缺少最后 3 个字符(y、z、终止字符(

另一个注意事项: 包装类的构造函数如下所示

zlib->zalloc = Z_NULL;
zlib->zfree = Z_NULL;
zlib->opaque = Z_NULL;
zlib->avail_in = 0;
zlib->next_in = Z_NULL;

首先,一堆没有上下文的分散代码片段使得无法看到发生了什么。请参阅如何创建最小、可重现的示例,了解如何提供一个体面的示例。

其次,你不是在说什么在回报Z_BUF_ERROR.在你的代码片段中甚至没有任何地方保留deflate()inflate()的返回值,所以你甚至不可能看到Z_BUF_ERROR!您至少需要执行类似int ret = deflate(zlib.get(), Z_FINISH);的操作,然后检查ret的值。

第三,我无法在您的代码片段中分辨出输入指针和长度的位置,甚至是否设置了输入指针和长度。初始化前的长度是否设置为零?还是设置为数据?还是在 init 之后设置数据指针和长度?请参阅上面的 MRE 链接。

第四,我们没有您正在使用的示例数据。因此,我们无法重现该错误。同样,请参阅 MRE 链接。

好的,所以在这里在黑暗中刺一下,我会猜测deflate()正在返回错误。那么问题很可能是你没有提供足够的输出空间,你要求Z_FINISH,这说明deflate()提供了足够的输出空间。在这种情况下,deflate()返回Z_BUF_ERROR意味着您没有。如果数据不可压缩,压缩可以扩展数据,并且 gzip 比 zlib 添加更多的标头和尾部信息。你的+ 8不足以解释这两件事。zlib 标头和尾部为 6 个字节,而 gzip 标头和尾部至少为 18 个字节。扩展是输入上的乘数,添加百分比的某些部分,而长度上根本没有乘数。

zlib 为此提供了一个函数,deflateBound().您将在输入大小deflateInit()后调用它,它将返回压缩输出的最大大小。

但是,最好在循环中多次调用deflate()。对于大多数实际应用,有必要在一个循环中多次调用inflate()。这在您的评论中以及您试图(也不足以(通过乘以一千来解释膨胀数据的可能大小中都可以看到。

您可以在 zlib 使用示例中找到有关如何正确使用 zlib 函数和循环的大量注释示例。

相关文章: