如何使用Boost IOStreams的Gzip文件界面逐行阅读?

时间:2011-06-21 05:10:42

标签: c++ boost file-io gzip iostream

我设法集成了boost Iostream API来读取压缩文件。我按照boost页面中的文档进行操作,并且到目前为止使用了以下代码:

std::stringstream outStr;  
ifstream file("file.gz", ios_base::in | ios_base::binary);  
try {  
    boost::iostreams::filtering_istreambuf in;  
    in.push(boost::iostreams::gzip_decompressor());  
    in.push(file);  
    boost::iostreams::copy(in, outStr);  
}  
catch(const boost::iostreams::gzip_error& exception) {  
    int error = exception.error();  
    if (error == boost::iostreams::gzip::zlib_error) {  
       //check for all error code    
    }   
}  

代码工作正常(所以请忽略任何拼写错误。以及上面的错误:))。

  1. 看起来上面的代码会在创建filtering_istreambuf时读取完整的文件并将其存储在内存中。这是真的吗,从我的调查看起来对我来说如此?如果文件被读入内存,这个代码可能是大文件的问题(这正是我正在处理的)。
  2. 我当前的代码逐行使用zlib中的gzgets API读取gzip。有没有办法使用boost API逐行读取?

1 个答案:

答案 0 :(得分:22)

1)是的,上面的代码将copy()整个文件放入字符串缓冲区outStr。根据{{​​3}}

  

函数模板副本从给定的Source模型中读取数据,并将其写入给定的Sink模型,直到到达流的末尾。

2)从filtering_istreambuf切换到filtering_istream并且std :: getline()将起作用:

#include <iostream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
int main()
{
    std::ifstream file("file.gz", std::ios_base::in | std::ios_base::binary);
    try {
        boost::iostreams::filtering_istream in;
        in.push(boost::iostreams::gzip_decompressor());
        in.push(file);
        for(std::string str; std::getline(in, str); )
        {
            std::cout << "Processed line " << str << '\n';
        }
    }
    catch(const boost::iostreams::gzip_error& e) {
         std::cout << e.what() << '\n';
    }
}

(如果你想要证明,你可以在那个循环中std::cout << file.tellg() << '\n';。它会增加相当大的块,但它不会等于从开始的文件长度)