boostのiostreamsを使ってgzipされたファイルを開く

以前C++でプロセスをPstreamsを使って開く方法について日記を書いたが,PstreamsはGPLなので,自分のソフトを修正BSDで公開したい場合には色々と面倒なのかなと思っており(全然問題ないのかもだが),常々他の方法,特に標準ライブラリ(もしくはそれに近いもの)で置き換えられないかと考えていた.

自分がやりたいのは,単にgzip圧縮されたファイルをストリームを使って読み込みたいというだけである.

Pstreamを使うと,開いたプロセスをストリームから読み込むことができるようになるので,gunzipでファイルを解凍するプロセスをPstreamに渡すことで,一応目的は達成していた.

Pstreamsでそれを行うには,以下のようにする.

#include <iostream>
#include "pstream.h"
using namespace std;

string command = "gunzip -c " + file;
istream *in = (istream *) (new redi::ipstream (command));

これで一応目的は達成できるが,先にも述べたとおり,ライセンスの問題もあるし,gunzipを使っているので,Windowsに移植する時に面倒くさいという話があった.

ライセンスの問題は,zlibや以前のこの日記で回避可能であるが,前者の方法はストリームとの組み合わせかたが良く分からないし,後者の方法はgunzipを使っている上にgccでしか使えない方法である.

zlibをストリームと組み合わせられたら一番良いのであるが,自分でほいほいと作れるほどその辺には精通していない.

が,この辺りの問題をBoost.Iostreamsが全部解決してくれたので,メモしておく.

boostのiostreamsを使ってgzip圧縮されたファイルをストリームから読み込むには以下の様にする.

#inlucd <iostream>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
using namespace std;
namespace io = boost::iostreams;

io::filtering_istream *fltr_is = new io::filtering_istream();
fltr_is->push(io::gzip_decompressor());
fltr_is->push(io::file_source(file));
istream *in = fltr_is;

boostのiostreamsでは,ファイルハンドルをストリームにすることも出来るみたいなので,popenをストリーム化することも出来そうである.