zlib-gzip的零压缩率 我有下面的C++代码,使用ZLIB压缩内存 缓冲区到gzip编码流中: void compress(const std::vector<char>& src) { static constexpr int DEFAULT_WINDOW_BITS = 15; static constexpr int GZIP_WINDOW_BITS = DEFAULT_WINDOW_BITS + 16; static constexpr int GZIP_MEM_LEVEL = 8; z_stream stream; const auto srcData = reinterpret_cast<unsigned char*>(const_cast<char*>(src.data())); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.next_in = srcData; stream.avail_in = src.size(); auto result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, GZIP_WINDOW_BITS, GZIP_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (result == Z_OK) { std::vector<char> dest(deflateBound(&stream, stream.avail_in)); const auto destData = reinterpret_cast<unsigned char*>(dest.data()); stream.next_out = destData; stream.avail_out = dest.size(); result = deflate(&stream, Z_FINISH); if (result == Z_STREAM_END) { std::cout << "Original: " << src.size() << "; compressed: " << dest.size() << std::endl; } else { std::cerr << "Error when compressing: code " << std::to_string(result); } result = deflateEnd(&stream); if (result != Z_OK) { std::cerr << "Error: Cannot destroy deflate stream: code " << std::to_string(result) << std::endl; } } else { std::cerr << "Error: Cannot initialize deflate stream: code " << std::to_string(result) << std::endl; } }

zlib-gzip的零压缩率 我有下面的C++代码,使用ZLIB压缩内存 缓冲区到gzip编码流中: void compress(const std::vector<char>& src) { static constexpr int DEFAULT_WINDOW_BITS = 15; static constexpr int GZIP_WINDOW_BITS = DEFAULT_WINDOW_BITS + 16; static constexpr int GZIP_MEM_LEVEL = 8; z_stream stream; const auto srcData = reinterpret_cast<unsigned char*>(const_cast<char*>(src.data())); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.next_in = srcData; stream.avail_in = src.size(); auto result = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, GZIP_WINDOW_BITS, GZIP_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (result == Z_OK) { std::vector<char> dest(deflateBound(&stream, stream.avail_in)); const auto destData = reinterpret_cast<unsigned char*>(dest.data()); stream.next_out = destData; stream.avail_out = dest.size(); result = deflate(&stream, Z_FINISH); if (result == Z_STREAM_END) { std::cout << "Original: " << src.size() << "; compressed: " << dest.size() << std::endl; } else { std::cerr << "Error when compressing: code " << std::to_string(result); } result = deflateEnd(&stream); if (result != Z_OK) { std::cerr << "Error: Cannot destroy deflate stream: code " << std::to_string(result) << std::endl; } } else { std::cerr << "Error: Cannot initialize deflate stream: code " << std::to_string(result) << std::endl; } },c++,gzip,zlib,C++,Gzip,Zlib,我做错什么了吗 (请注意,这是原始代码的简化版本;在实践中,我将使用RAII和异常进行资源和错误处理)。关于这个问题的注释就是答案,所以请将它们记录在这里以供后代使用 dest.size()。从dest.size()得到的只是压缩前输出缓冲区的大小。您需要查看从deflate()调用返回的内容,以确定压缩结果的大小。可以是dest.size()-strm.avail\u out,也可以是strm.total\u out 在单个调用中进行压缩意味着您需要在一个无符号的中同时调整输入和输出缓冲区大小

我做错什么了吗


(请注意,这是原始代码的简化版本;在实践中,我将使用RAII和异常进行资源和错误处理)。

关于这个问题的注释就是答案,所以请将它们记录在这里以供后代使用

dest.size()。从
dest.size()
得到的只是压缩前输出缓冲区的大小。您需要查看从
deflate()
调用返回的内容,以确定压缩结果的大小。可以是
dest.size()-strm.avail\u out
,也可以是
strm.total\u out

在单个调用中进行压缩意味着您需要在一个
无符号的
中同时调整输入和输出缓冲区大小,通常为32位。因此,您只能压缩大约4GB的数据。如果您可能需要做更多的工作,那么您将需要一个循环,为较小的块调用
deflate()
。可能更小的数据块,以10或100千字节为单位。这是使用
deflate()
的常用方法,因为它占用的内存要少得多,并且可以防止例程在这方面占用资源


deflateBound()
专门用于支持单个
deflate()
调用的使用。它提供了一个可能的压缩大小上限,它可以是比输入数据大一点点的大小。当输入数据是不可压缩的,例如已经压缩或随机的时,就是这种情况。

对问题的评论就是答案,所以请将它们记录在这里,以供子孙后代使用

dest.size()。从
dest.size()
得到的只是压缩前输出缓冲区的大小。您需要查看从
deflate()
调用返回的内容,以确定压缩结果的大小。可以是
dest.size()-strm.avail\u out
,也可以是
strm.total\u out

在单个调用中进行压缩意味着您需要在一个
无符号的
中同时调整输入和输出缓冲区大小,通常为32位。因此,您只能压缩大约4GB的数据。如果您可能需要做更多的工作,那么您将需要一个循环,为较小的块调用
deflate()
。可能更小的数据块,以10或100千字节为单位。这是使用
deflate()
的常用方法,因为它占用的内存要少得多,并且可以防止例程在这方面占用资源


deflateBound()
专门用于支持单个
deflate()
调用的使用。它提供了一个可能的压缩大小上限,它可以是比输入数据大一点点的大小。当输入数据是不可压缩的,例如已经压缩或随机的时,就是这种情况。

为什么要使用
dest.size()
而不是
stream.total\u out
?噢,该死。。你说得对,这的确显示出更小的尺寸。但是,为什么deflateBound一开始就给出了这么大的数字?“deflateBound()和compressBound()函数可用于提供扩展的上限,以便允许分配足够大的输出缓冲区,以容纳整个压缩输出。”-上限=最坏情况如果您想看到最坏的情况发生,请使用随机或加密数据作为输入为什么要使用
dest.size()
而不是
stream.total\u out
?哦,糟糕。。你说得对,这的确显示出更小的尺寸。但是,为什么deflateBound一开始就给出了这么大的数字?“deflateBound()和compressBound()函数可用于提供扩展的上限,以便允许分配足够大的输出缓冲区,以容纳整个压缩输出。”-上限=最坏情况如果您希望看到最坏情况发生,请使用随机或加密数据作为输入
Original: 3205841; compressed: 3206843