如何使用 boost iostreams 进行流式解压缩
How to streaming decompress using boost iostreams
我正在使用 boost iostreams (1.64.0) 来解压缩 zlib 数据。
我想做流式解压。这意味着压缩数据的大小不可预测。
我写了下面的代码示例。
#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] = { '[=10=]' };
#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;
}
我使用readsome()
因为数据的大小是不可预测的。
我得到以下输出:
read_size:0
rdstate:0
出乎我的意料。
如果我使用 getline()
而不是 readsome()
,我得到以下输出:
rdstate:2
Hello World
这是预期的输出。
我想当我使用readsome()
时,输出应该是一样的。
我无法在实际代码中使用 getline()
我的,因为原始数据是二进制格式。
有什么方法可以将 readsome()
与 filtering_streambuf
一起使用,或者有什么好的方法可以流式解压缩不可预测长度的二进制数据吗?
感谢,问题解决
我为评论写了,但很难阅读,因为代码格式不正确。所以我自己回答。希望对其他遇到类似问题的人有所帮助。
我替换了
std::size_t read_size = is.readsome(buf, buf_size);
和
is.read(buf, buf_size);
std::size_t read_size = is.gcount();
,问题解决
我误解了 std::istream::read
块直到读取 buf_size
长度数据。这不是真的。即使实际读取大小小于buf_size,函数returns。参见 http://www.cplusplus.com/reference/istream/istream/read/. In order to get read_size
, I call std::istream::gcount()
. See http://www.cplusplus.com/reference/istream/istream/gcount/。
注意:我对 boost::asio::read
and boost::asio::ip::tcp::socket::read_some
感到困惑。但他们的行为与std::istream
的不同。
修复版的完整代码如下:
#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] = { '[=12=]' };
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;
}
我正在使用 boost iostreams (1.64.0) 来解压缩 zlib 数据。 我想做流式解压。这意味着压缩数据的大小不可预测。 我写了下面的代码示例。
#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] = { '[=10=]' };
#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;
}
我使用readsome()
因为数据的大小是不可预测的。
我得到以下输出:
read_size:0
rdstate:0
出乎我的意料。
如果我使用 getline()
而不是 readsome()
,我得到以下输出:
rdstate:2
Hello World
这是预期的输出。
我想当我使用readsome()
时,输出应该是一样的。
我无法在实际代码中使用 getline()
我的,因为原始数据是二进制格式。
有什么方法可以将 readsome()
与 filtering_streambuf
一起使用,或者有什么好的方法可以流式解压缩不可预测长度的二进制数据吗?
感谢
我为评论写了
我替换了
std::size_t read_size = is.readsome(buf, buf_size);
和
is.read(buf, buf_size);
std::size_t read_size = is.gcount();
,问题解决
我误解了 std::istream::read
块直到读取 buf_size
长度数据。这不是真的。即使实际读取大小小于buf_size,函数returns。参见 http://www.cplusplus.com/reference/istream/istream/read/. In order to get read_size
, I call std::istream::gcount()
. See http://www.cplusplus.com/reference/istream/istream/gcount/。
注意:我对 boost::asio::read
and boost::asio::ip::tcp::socket::read_some
感到困惑。但他们的行为与std::istream
的不同。
修复版的完整代码如下:
#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] = { '[=12=]' };
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;
}