我正在使用boost iostreams读取一个gzip压缩文件: 以下工作正常:
namespace io = boost::iostreams;
io::filtering_istream in;
in.push(boost::iostreams::basic_gzip_decompressor<>());
in.push(io::file_source("test.gz"));
stringstream ss;
copy(in, ss);
但是,我不想把读取整个gzip压缩文件的内存命中 进入记忆。我希望能够逐步读取文件。
例如,如果我有一个从istream初始化自己的数据结构,
X x;
x.read(in);
失败。大概这是因为我们可能不得不将字符放回流中 如果我们正在做部分流。有关boost iostreams支持的任何想法吗?
答案 0 :(得分:1)
根据iostream documentation类型boost::io::filtering_istream
来自std::istream
。也就是说,应该可以在预期std::istream&
的任何地方传递它。如果您在运行时遇到错误,因为您需要unget()
或putback()
个字符,那么您应该查看pback_size
参数,该参数指定最多返回多少个字符。我没有在文档中看到此参数的默认值是什么。
如果这不能解决您的问题,您能描述一下您的问题究竟是什么吗?从它的外观来看应该有效。
答案 1 :(得分:1)
我认为您需要编写自己的过滤器。例如,要读取.tar.gz并输出包含的文件,我写了类似
的内容//using namespace std;
namespace io = boost::iostreams;
struct tar_expander
{
tar_expander() : out(0), status(header)
{
}
~tar_expander()
{
delete out;
}
/* qualify filter */
typedef char char_type;
struct category :
io::input_filter_tag,
io::multichar_tag
{ };
template<typename Source>
void fetch_n(Source& src, std::streamsize n = block_size)
{
/* my utility */
....
}
// Read up to n filtered characters into the buffer s,
// returning the number of characters read or -1 for EOF.
// Use src to access the unfiltered character sequence
template<typename Source>
std::streamsize read(Source& src, char* s, std::streamsize n)
{
fetch_n(src);
const tar_header &h = cast_buf<tar_header>();
int r;
if (status == header)
{
...
}
std::ofstream *out;
size_t fsize, stored;
static const size_t block_size = 512;
std::vector<char> buf;
enum { header, store_file, archive_end } status;
}
}
调用时我的函数read(Source &...)
会收到解压缩的文本。
要使用过滤器:
ifstream file("/home/..../resample-1.8.1.tar.gz", ios_base::in | ios_base::binary);
io::filtering_streambuf<io::input> in;
in.push(tar_expander());
in.push(io::gzip_decompressor());
in.push(file);
io::copy(in, cout);