ストリーム関連クラス 1
前回の記事のテキスト処理とも関連しているのがストリームです。POCOでは、ストリーム処理に関係するクラスがなぜかとても豊富に実装されていて、「Streams」というパッケージには53クラスも含まれています。ここでは、実用度が高いと思われるものを独断でピックアップし、サンプルコードを紹介することにしましょう。
種別 | 概要 | クラス名 |
ストリーム | 基本のファイル読み書きストリーム | FileStream、FileInputStream、FileOutputStream |
文字カウント・ストリーム | CountingInputStream、CountingOutputStream | |
BASE64変換ストリーム | Base64Decoder、Base64Encoder | |
HEXバイナリ変換ストリーム | HexBinaryDecoder、HexBinaryEncoder | |
圧縮ストリーム | DeflatingOutputStream、DeflatingOutputStream | |
伸張ストリーム | InflatingInputStream、InflatingOutputStream | |
バイナリデータ操作ストリーム | BinaryReader、BinaryWriter | |
その他 | ストリーム・コピー | StreamCopier |
ストリーム・トークナイザー | StreamTokenizer | |
改行コード変換 | InputLineEndingConverter |
ストリームクラスは、基本的には出力専用クラス(~OutputStream)、入力専用クラス(~InputStream)があり、中には入出力クラスが用意されているものもあります。
基本のファイル読み書きストリーム
まずは、基本のファイル読み書きのストリームです。少し変わっているのが、ファイルが常にバイナリモード(std::ios::binaryフラグが付加される)でオープンされることです。つまり、改行コードの自動変換がこのクラスではされないということです。「\n」をプラットフォームに応じた改行コードに変換するためには、別途「Poco::InputLineEndingConverter」「Poco::OutputLineEndingConverter」を利用する必要があります。
Poco::FileInputStream、Poco::FileOutputStreamの基底クラスは、それぞれstd::istream、std::ostreamなので、通常のストリームとしての操作が行えます。それ以外に特別なメンバ関数は実装されていません。ファイルストリームへの読み書きサンプルコードは次のようになります。
#include <Poco/FileStream.h> #include <Poco/LineEndingConverter.h> // ファイルストリームへの書き込み Poco::FileStream out_stream( "c:\\temp\\temp.txt" ); Poco::OutputLineEndingConverter conv( out_stream ); conv << "test" << std::endl; // 改行コードが正しく変換される out_stream.close(); // ファイルストリームから読み込む Poco::FileStream in_stream( "c:\\temp\\temp.txt" ); char c; in_stream.get(c); // 1バイト取り出す // 「first -> t 」と表示される std::cout << "first -> " << c << std::endl;
BASE64変換ストリーム
BASE64変換用としてフィルタのように使用するクラスです。
BASE64とは、データを64種類の印字可能な英数字のみを用いて表すエンコードです。テキストデータしか載せられない電子メールでバイナリデータを扱うときにおなじみですね。
#include <Poco/FileStream.h> #include <Poco/Base64Encoder.h> #include <Poco/Base64Decoder.h> #include <Poco/StreamCopier.h> Poco::FileStream tmp_stream( "c:\\temp\\temp.txt" ); // BASE64に変換して、出力 Poco::Base64Encoder base64Out( tmp_stream ); // シフトJIS -> BASE64 に変換 base64Out << "これはテスト" << "\n" << "文字列です"; // バイナリデータ(改行)もOK tmp_stream.seekp( 0 ) ; // ファイルポインタを先頭に // BASE64 -> シフトJIS に変換 Poco::Base64Decoder base64Input( tmp_stream ); // ストリームコピー(static関数)で、std::coutに出力 Poco::StreamCopier::copyStream( base64Input, std::cout );
サンプルコードはファイルストリームにBASE64に変換した文字列を書き込み、次にそのファイルからデータを読み出して復号し、画面に出力するものです。実行するとコンソール画面には、
これはテスト 文字列です
と表示されます。改行コードのバイナリデータも復号できています。「temp.txt」ファイルを見てみると、
grGC6oLNg2WDWINnCpW2jpqX8YLFgrcK
というBASE64に変換した文字列が書き込まれているはずです。
圧縮・伸張ストリーム
これもBASE64変換ストリームと同様な使い方ができるクラスで、データの圧縮とその復号を行うストリームです。圧縮アルゴリズムの実装は、zlibという広く使われている圧縮ライブラリを利用しており、圧縮のタイプとしてzlib形式とgzip形式が指定できます。このクラスを利用すると、手軽に圧縮解凍処理をプログラムに組み込むことができます。
#include "Poco/InflatingStream.h" #include "Poco/DeflatingStream.h" Poco::FileStream out_stream( "c:\\temp\\temp.gz" ); // 圧縮ストリーム Poco::DeflatingOutputStream deflater(out_stream, Poco::DeflatingStreamBuf::STREAM_GZIP); // gzip形式 // 圧縮されて書き込まれる deflater << "Hello, world!" << std::endl; deflater.close(); out_stream.close(); Poco::FileStream in_stream( "c:\\temp\\temp.gz" ); // 伸張ストリームで、復元 Poco::InflatingInputStream inflater(in_stream, Poco::InflatingStreamBuf::STREAM_GZIP); // static関数のcopyStreamで、inflaterの内容をstd::coutに出力 // copyStreamは、ストリームの内容を丸ごと別のストリームに書き込める Poco::StreamCopier::copyStream( inflater, std::cout );
gzip形式で書き込んだ「temp.gz」を読み込み、データを伸張して表示しています。コンソール画面には、書き込んだ文字列の「Hello, world!」が表示されます。「temp.gz」ファイルはgzipに対応したツールで解凍することも可能です。