6

ブースト iostream を使用して gzip されたファイルを読み込んでいます: 以下は正常に動作します:

 namespace io = boost::iostreams;
  io::filtering_istream in;
  in.push(boost::iostreams::basic_gzip_decompressor<>());
  in.push(io::file_source("test.gz"));
  stringstream ss;
  copy(in, ss);

ただし、gzip で圧縮されたファイル全体をメモリに読み込むというメモリ ヒットは避けたいと思います。ファイルを段階的に読み取れるようにしたい。

たとえば、istream から自身を初期化するデータ構造 X がある場合、

X x;
x.read(in);

失敗します。おそらくこれは、部分ストリームを実行している場合、文字をストリームに戻さなければならない可能性があるためです。ブースト iostreams がこれをサポートしているかどうかのアイデアはありますか?

4

2 に答える 2

1

独自のフィルターを作成する必要があると思います。たとえば、.tar.gz を読み取り、そこに含まれるファイルを出力するには、次のように記述します。

//using namespace std;
namespace io = boost::iostreams;

struct tar_expander
{
    tar_expander() : out(0), status(header)
    {
    }
    ~tar_expander()
    {
        delete out;
    }

    /* qualify filter */
    typedef char char_type;
    struct category :
        io::input_filter_tag,
        io::multichar_tag
    { };

    template<typename Source>
    void fetch_n(Source& src, std::streamsize n = block_size)
    {
           /* my utility */
           ....
    }

    // Read up to n filtered characters into the buffer s,
    // returning the number of characters read or -1 for EOF.
    // Use src to access the unfiltered character sequence
    template<typename Source>
    std::streamsize read(Source& src, char* s, std::streamsize n)
    {
      fetch_n(src);
      const tar_header &h = cast_buf<tar_header>();
      int r;

      if (status == header)
      {
          ...
      }
      std::ofstream *out;
      size_t fsize, stored;

      static const size_t block_size = 512;
      std::vector<char> buf;

      enum { header, store_file, archive_end } status;
   }
}

私の関数read(Source &...)は、呼び出されたときに解凍されたテキストを受け取ります。フィルタを使用するには:

ifstream file("/home/..../resample-1.8.1.tar.gz", ios_base::in | ios_base::binary);
io::filtering_streambuf<io::input> in;
in.push(tar_expander());
in.push(io::gzip_decompressor());
in.push(file);
io::copy(in, cout);
于 2012-02-28T22:45:13.070 に答える
1

iostream のドキュメントによると、型boost::io::filtering_istreamは から派生しstd::istreamます。つまり、std::istream&予期されるあらゆる場所でこれを渡すことができるはずです。unget()またはputback()文字が必要なために実行時にエラーが発生した場合は、pback_size返される最大文字数を指定するパラメーターを確認する必要があります。このパラメーターのデフォルト値が何であるかをドキュメントで見たことがありません。

これで問題が解決しない場合は、問題の内容を正確に説明できますか? 見た目から、うまくいくはずです。

于 2012-02-28T22:21:06.553 に答える