【问题标题】:How can I read line-by-line using Boost IOStreams' interface for Gzip files?如何使用 Boost IOStreams 的 Gzip 文件接口逐行读取?
【发布时间】:2011-09-19 05:19:30
【问题描述】:

我设法集成了用于读取压缩文件的 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. 我当前的代码使用 gzgets API 从 zlib 中逐行读取 gzipped。有没有办法使用 boost API 逐行阅读?

【问题讨论】:

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


    【解决方案1】:

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

    函数模板副本从给定的 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 &lt;&lt; file.tellg() &lt;&lt; '\n';。它会增加相当大的块,但它不会等于文件从一开始的长度)

    【讨论】:

    • 谢谢。让我试试这个。我希望将 存储为班级成员。并在类中有一个名为 getline 的成员函数。 getline 应该能够从当前文件指针位置返回行。
    • 我尝试在循环内打印流位置,但它不起作用。如果我使用std::ifstreamfile.tellg() 返回一个常数,如果我使用boost::iostream::file_source,则返回 0。如果我在 in 流上调用它,它会返回 -1。如何获得文件中的当前位置并能够移动到该位置?我是否必须先将所有流转储到另一个流中?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多