[英]How to streaming decompress using boost iostreams
I'm using boost iostreams (1.64.0) in order to decompress zlib data. 我正在使用boost iostreams(1.64.0)来解压缩zlib数据。 I want to do streaming decompression.
我想进行流式减压。 That means the compressed data are unpredictable size.
这意味着压缩数据的大小无法预测。 I wrote the following code example.
我编写了以下代码示例。
#include <sstream>
#include <string>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
int main() {
// Compress
std::stringstream sender;
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
out.push(boost::iostreams::zlib_compressor());
out.push(sender);
sender << "Hello World";
std::stringstream compressed;
boost::iostreams::copy(out, compressed);
// Decompress
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(compressed);
std::istream is(&in);
std::size_t const buf_size = 256;
char buf[buf_size] = { '\0' };
#if 0
is.getline(buf, buf_size); // works fine
#else
std::size_t read_size = is.readsome(buf, buf_size);
std::cout << "read_size:" << read_size << std::endl;
#endif
// http://www.cplusplus.com/reference/ios/ios/rdstate/
std::cout << "rdstate:" << is.rdstate() << std::endl;
std::cout << buf << std::endl;
}
I use readsome()
because the size of data is unpredictable. 我使用
readsome()
因为数据的大小是不可预测的。 I got the following output: 我得到以下输出:
read_size:0
rdstate:0
It was unexpected for me. 这对我来说是出乎意料的。
If I use getline()
instead of readsome()
, I got the following output: 如果我使用
getline()
而不是readsome()
, readsome()
得到以下输出:
rdstate:2
Hello World
It was expected output. 这是预期的输出。
I think that when I use readsome()
, the out put should be the same. 我认为当我使用
readsome()
,输出应该相同。 I can't use getline()
my in actual code because the original data is binary format. 我不能在实际代码中使用
getline()
,因为原始数据是二进制格式。
Is there any way to use readsome()
with filtering_streambuf
or any good way to streaming decompress unpredictable length binary data? 有什么方法可以将
readsome()
与filtering_streambuf
一起使用,或者有什么好的方法以流方式解压缩不可预测长度的二进制数据?
Thanks to sehe's comment , the problem is solved. 感谢sehe的评论 ,问题得以解决。
I wrote the response for the comment but it is difficult to read because codes are not well formatted. 我为评论写了响应 ,但是由于代码格式不正确,很难阅读。 So I answer by myself.
所以我自己回答。 I hope it will help for other people who have similar problem.
希望对其他有类似问题的人有所帮助。
I replaced 我更换了
std::size_t read_size = is.readsome(buf, buf_size);
with 同
is.read(buf, buf_size);
std::size_t read_size = is.gcount();
, then problem is solved. ,那么问题就解决了。
I had misunderstood that std::istream::read
blocks until reading buf_size
length data. 我误解了
std::istream::read
块,直到读取buf_size
长度数据。 It is not true. 这不是真的。 Even if the actual read size is less than buf_size, the function returns.
即使实际读取的大小小于buf_size,该函数也会返回。 See http://www.cplusplus.com/reference/istream/istream/read/ .
参见http://www.cplusplus.com/reference/istream/istream/read/ 。 In order to get
read_size
, I call std::istream::gcount()
. 为了获得
read_size
,我调用了std::istream::gcount()
。 See http://www.cplusplus.com/reference/istream/istream/gcount/ . 参见http://www.cplusplus.com/reference/istream/istream/gcount/ 。
NOTE: I had gotten confused with boost::asio::read
and boost::asio::ip::tcp::socket::read_some
. 注意:我对
boost::asio::read
和boost::asio::ip::tcp::socket::read_some
。 But their behavior are different from std::istream
's one. 但是它们的行为不同于
std::istream
的行为。
Here is the complete code of the fixed version: 这是固定版本的完整代码:
#include <sstream>
#include <string>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
int main() {
// Compress
std::stringstream sender;
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
out.push(boost::iostreams::zlib_compressor());
out.push(sender);
sender << "Hello World";
std::stringstream compressed;
boost::iostreams::copy(out, compressed);
// Decompress
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(compressed);
std::istream is(&in);
std::size_t const buf_size = 256;
char buf[buf_size] = { '\0' };
is.read(buf, buf_size);
std::size_t read_size = is.gcount();
std::cout << "read_size:" << read_size << std::endl;
// http://www.cplusplus.com/reference/ios/ios/rdstate/
std::cout << "rdstate:" << is.rdstate() << std::endl;
std::cout << buf << std::endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.