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

How can I read line-by-line using Boost IOStreams' interface for Gzip files?

本文关键字:读取 Gzip 文件 逐行 界面 何使用 Boost IOStreams      更新时间:2023-10-16

我设法集成了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进行逐行读取

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

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