ZLib GZIP返回Z_BUF_ERROR(-5)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZLib GZIP返回Z_BUF_ERROR(-5)相关的知识,希望对你有一定的参考价值。
我正在使用zlib库(从src编译)来压缩/膨胀gzip / zlib / raw字节。我创建了一个用于解压缩的包装类(Compressor / Decompresser)。我还创建了几个测试用例(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);
Input被设置为另一个函数(正在被调用),看起来像这样。 (调用compress / decompress时不会删除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配对),ZLib
和RAW
的测试用例起作用。 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;
首先,一堆没有上下文的分散的代码片段使无法看到正在发生的事情。请参见How to create a Minimal, Reproducible Example以获取如何提供一个体面的示例。
第二,您不是说what返回Z_BUF_ERROR
。您的代码段中甚至没有保留deflate()
或inflate()
返回值的地方,因此甚至看不到Z_BUF_ERROR
!您至少需要执行int ret = deflate(zlib.get(), Z_FINISH);
之类的操作,然后检查ret
的值。
[第三,我无法在您的代码片段中告诉您设置输入指针和长度的位置或位置。在初始化之前将长度设置为零吗?还是设置为数据?还是在初始化之后设置数据指针和长度?请参阅上面的MRE链接。
第四,我们没有您正在使用的示例数据。因此,我们无法重现该错误。再次,请参阅MRE链接。
[好,所以在这里暗中刺刺,我猜想deflate()
正在返回错误。那么问题可能出在您没有提供足够的输出空间,而您要求了Z_FINISH
,这告诉deflate()
您have提供了足够的输出空间。在这种情况下,deflate()
返回Z_BUF_ERROR
表示您没有。如果数据不可压缩,则压缩可以扩展数据,并且gzip比zlib添加更多的头和尾信息。您的+ 8
不足以说明这两件事。 zlib的标头和结尾为6个字节,而gzip的标头和结尾为至少18个字节。扩展是输入的乘数,加上百分比的一部分,在长度上根本没有乘数。
zlib为此提供了一个功能,deflateBound()
。您可以在deflateInit()
之后用输入的大小调用它,它将返回压缩输出的最大大小。
但是最好在循环中多次调用deflate()
。对于大多数实际应用,有必要在一个循环中多次调用inflate()
。在您的评论中以及您试图(也不足以)乘以一千来解释膨胀数据的可能大小时,都可以看到这一点。
您可以在zlib Usage Example上找到有关如何正确使用带循环的zlib函数的详细注释示例。
以上是关于ZLib GZIP返回Z_BUF_ERROR(-5)的主要内容,如果未能解决你的问题,请参考以下文章