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をストリーム化することも出来そうである.