boost::iostreams
非圧縮テキストファイルの読み取りに使用しています。私のアプリケーションでは、このファイルに格納されているさまざまなパラメーターのデータを効率的にバッファリングするために、(マップに格納されている) 複数のファイル ハンドルが必要です。また、行を読んで、現在関心のある時間よりも後でパラメーターを使用する場合は、ストリームの位置 (を介して回復tellg()
) を呼び出す前の場所に復元するため、getline()
引き続きバッファリングできます。将来の時点でのこの値。
ただし、gzip 圧縮ファイルを読みたいのですが、それ以外は以前と同じ操作を実行します。次の問題に出くわしました (以前に発見されましたが、ソリューションは要件のトリプレットでは機能しないようです)。
これらの問題を再現する短いテストmain()
は次のとおりです。
#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 は、デコンプレッサ オブジェクトをこのタイプのフィルタにプッシュできないことを示しています。これに対する回避策は見つかりませんでした。