boost :: iostreams,gzip文件和tellg

时间:2013-08-07 15:57:05

标签: c++ gzip getline

我一直在使用boost :: iostreams来读取未压缩的文本文件。在我的应用程序中,我需要多个文件句柄(存储在一个映射中)来有效地缓冲存储在该文件中的不同参数的数据。另外,如果我读取一行并且它的参数比我目前感兴趣的时间晚,我将流位置(通过tellg()恢复)恢复到我调用getline()之前的位置,这样我仍然可以将来缓冲此值。但是,我现在希望阅读gzip压缩文件,否则执行与以前相同的操作。我遇到了以下问题(之前发现过,但解决方案似乎不符合我的三重要求)。一个简短的测试主()重现了这些问题:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <boost/shared_ptr.hpp>// shared_ptr
#include <boost/iostreams/filtering_stream.hpp>// filtering_[io]stream
#include <boost/iostreams/filter/gzip.hpp>// gzip

//-----------------------------------------------------------------------------

int main( int argc, char** argv ){

    std::cout << std::scientific << std::setprecision(15) << std::endl;
    std::string fileName("test.txt.gz");
    bool gzipped(true);
    std::string line;

    // TEST 1
    boost::shared_ptr<std::ifstream> fileStream1;
    boost::shared_ptr<boost::iostreams::filtering_istream> fileFilter1;
    fileFilter1.reset( new boost::iostreams::filtering_istream );
    fileStream1.reset( new std::ifstream( fileName.c_str() ) );
    if(gzipped)
        fileFilter1->push( boost::iostreams::gzip_decompressor() );
    fileFilter1->push( *fileStream1 );
    while( std::getline( *fileFilter1, line ) ){
        //std::streampos strPos( fileFilter1->tellg() );// uncomment this line for run-time errors
        std::cout << line << std::endl;
    }
    std::cout << std::endl;

    // TEST 2
    boost::shared_ptr<std::ifstream> fileStream2;
    boost::shared_ptr<boost::iostreams::filtering_stream<boost::iostreams::input_seekable> > fileFilter2;
    fileFilter2.reset( new boost::iostreams::filtering_stream<boost::iostreams::input_seekable>() );
    fileStream2.reset( new std::ifstream( fileName.c_str() ) );
    //fileFilter2->push( boost::iostreams::gzip_decompressor() );// uncomment this line for compile-time errors
    fileFilter2->push( *fileStream2 );
    while( std::getline( *fileFilter2, line ) ){
        std::streampos strPos( fileFilter2->tellg() );
        std::cout << line << std::endl;
    }
    std::cout << std::endl;

    return 0;
}

在这种情况下,输入文件显然可以包含您喜欢的任何内容。只需确保它有> 1行文本即可查看tellg()问题。

在TEST1中,我只能想象这些错误是由tellg()的哨兵创建和failbit修改(http://www.cplusplus.com/reference/istream/istream/sentry/)引起的?!?这篇文章(https://svn.boost.org/trac/boost/ticket/2449)表明:

boost::iostreams::filtering_stream<boost::iostreams::input_seekable>

将克服tellg()问题。但是,TEST2显示我无法将解压缩器对象推送到此类型的过滤器上。我还没有找到解决方法。

这是我第一次在这里发帖,如果我的问题有格式问题,请道歉!

非常感谢您提供的任何帮助,以及任何时候您可能会花费沉思!

0 个答案:

没有答案