2006年02月15日

オブジェクトの入出力(ストリームの利用)

バイト単位の入出力ではなく、より抽象度の高い入出力を実現するために、C++ではストリーム演算子が提供されています。Series60でも同様のストリーム演算子が提供されており、Unicode文字列の入出力などはこのストリームを用いたほうがより簡単に行うことができます。

 このストリームを用いた入出力はRFsクラスを用いてRWriteStream とRReadStreamを作成することで実現できます(特に、書き出す対象がファイルの場合はRFileWriteStream およびRFileReadStreamになります)。

Unicode文字列のストリームを用いた出力

 ここでは、先のサンプルのコードを書き換え、Unicode文字列の入出力が可能なサンプルを見て行きたいと思います(FileTest2.zip)。

 ファイルへの書き出しは次のようになっています。

void CFileTestDocument::WriteFile()
{
RFs& rfs = CCoeEnv::Static()->FsSession();
// ファイルサーバへのセッションを取り出し
RFileWriteStream wStream ;
TInt rst = wStream.Create( rfs,
_L("c:\\temp\\test.txt"), EFileWrite | EFileStreamText );
if( rst == KErrAlreadyExists ){
wStream.Open( rfs,
_L("c:\\temp\\test.txt"), EFileWrite | EFileStreamText );
}

_LIT( KOutputText , "こんにちは" );
wStream << KOutputText ; // ストリームを使っての書き出し
wStream.Close();
}

 先ほどのサンプル(FileTest1.zip)との相違は、RFileを用いるのではなく、RfileWriteStreamを用いているのが一点、次に、

WStream << KOutputText ; // ストリームを使っての書き出し

と、ストリーム演算子(<<)を用いている点。最後に_LIT8マクロではなく、Unicode文字列を生成する_LITマクロを使用している点です。ファイルの読み込みも同様に行っていますので、CFileTestDocument::ReadFile()関数をご参照ください。

ストリーム演算子とExternalizeLとInternalizeL関数

 FileTest2.zipでは、Unicode文字列の読み込みと書き込みを行いました。これに対して、プログラマ作成の任意のオブジェクトをストリーム演算子を用いて書き出す場合、内部的には(C++のテンプレートを用いて)ExternalizeLとInternalizeLの関数を呼び出します。

 つまり、wStream をRWriteStream のインスタンスとすれば、

WStream << someObj;

と、

SomeObj.ExternalizeL( wStream );

は同じ挙動をします。

 ですので、プログラマ作成の任意のオブジェクトに対して、ストリーム演算子を利用したいときは、ExternalizeL関数とInternalizeL関数を用意します。

 もう一点注意が必要な点として、ストリーム演算子が呼び出すExternalizeL関数とInternalizeL関数は最後に「L」がついていることからわかるとおり、リーブを発生します。ですから、ストリーム演算子はリーブを発生する可能性がある点に注意してください。

 組み込みのデータ型に関しては、ストリーム演算子はストリーム演算子のインスタンスがもつ以下のメンバ関数を順次呼び出します。

TInt8 WriteInt8L() ReadInt8L()
TInt16 WriteInt16L() ReadInt16L()
TInt32 WriteInt32L() ReadInt32L()
TUint8 WriteUint8L() ReadUint8L()
TUint16 WriteUint16L() ReadUint16L()
TUint32 WriteUint32L() ReadUint32L()
TReal32 WriteReal32L() ReadReal32L()
TReal64 WriteReal64L() ReadReal64L()

 ここで注意が必要なのが、TInt 型です。TInt型は次のようにtypedef されていますので、データサイズは実行環境に依存します。

typedef signed int TInt;

 ですから、TInt に関してはWriteInt32L() やReadInt32L() などを用いる必要があります。

ファイル入出力を使用する際にリンクするライブラリ

 今回はファイル入出力を用いたサンプルを提供しましたが、ご自身でスクラッチからプログラムを書く場合は、リンクするライブラリを追加する必要があります。そのため、プロジェクトの設定ファイルを変更する必要があります。

 追加が必要なライブラリの例としては、RFileクラスを使用する場合、実装はefsrv.libにあります。また、ファイルへのストリームを使う場合はestor.libに実装が提供されています。

 これらのライブラリはプロジェクトの設定ファイルであるMMPファイルにて、指定する必要があります。具体的には今回お配りしたサンプル(FileTest2.zip)ではFileTest.mmpにて、次のようにestore.libの指定がなされています。ご確認ください。

LIBRARY eikcoctl.lib avkon.lib estor.lib
posted by シンビアン at 16:41| Comment(0) | TrackBack(0) | Series60プログラミングテクニック | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。