前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

17.2. 文字列ストリーム

文字列ストリームは、文字列を読み書きするためのストリームです。 下記の表にあるように、文字列の型と読み書きのタイプに応じて 4 種類の文字列ストリームが存在します。

表 17.4. 文字列ストリーム

文字列の型 読み込み用 書き込み用
AChar 型 SFXAnsiStringStreamReader SFXAnsiStringStreamWriter
WChar 型 SFXWideStringStreamReader SFXWideStringStreamWriter

17.2.1. 文字列ストリームを利用した文字列クラスの読み書き

文字列ストリームでは、 ReadSFXAnsiString / ReadSFXWideString 関数や WriteSFXAnsiString / WriteSFXWideString 関数の引数、または インサータ(<< 演算子)やエクストラクタ(>> 演算子) のオペランドに SFXAnsiString / SFXWideString インスタンスを指定することで文字列クラスのデータをストレージに読み書きできます。

17.2.1.1. 文字列ストリームから文字列クラスへの読み込み

文字列ストリームから文字列クラスのデータを読み込む場合、 次の '\0'、または終端までのデータを SFXAnsiString / SFXWideString 型変数に読み込みます。

この場合、予めその変数のサイズを指定する必要はありません。 変数のメモリ領域は、 読み込んだ文字列の長さに合わせて自動的に確保されます。

[Note] バッファクラスに読み込む場合

SFXBuffer 型変数にデータを読み込む場合は、 予めその変数のサイズを指定する必要があります。 変数のメモリ領域は自動的に確保されません。

[Tip] '\0' セパレータ
ストリーム内で文字列を区切るセパレータである '\0' は、 AChar 型文字列(SFXAnsiString)の場合は 1 バイト、 WChar 型文字列(SFXWideString)の場合は 2 バイトです。
[Caution] バイナリストリームから文字列クラスを読み込む場合

バイナリストリームから文字列を読み込む場合、 終端までに次の '\0' が見つからないとエラーになり、 文字列は変数に格納されません(変数の内容は読み込む前の状態のままです)。

このとき、バイナリストリームの ReadSFXAnsiString / ReadSFXWideString 関数は SFERR_INVALID_STATE を返しますが、 エクストラクタ(>> 演算子)はエラーを返しません。

例 17.1. 読み込む文字列: "/dir/data.txt"

61 62 63 64 00 65 66 67 68 00 69 6A 6B 6C  // HEX 形式(16 進数表示)

例 17.2. 文字列ストリームから文字列クラスへの読み込み

// *** 以下のコードでは、エラー処理が省略されています。 
SFXFile file;                     // ファイル
SFXAnsiStringStreamReader reader; // ファイル読み込み用文字列ストリーム
SFXAnsiString string;             // 読み込む文字列

// 読み込みモードでファイルを開く
file.OpenReadOnly(SFXPath("/dir/data.txt"));

// ファイル読み込み用文字列ストリームを取得する
// ※ size 引数を指定していないのでストリームバッファは可変長
file.GetStreamReader(&reader);

// ファイルからストリームバッファにデータを読み込む
// ※1. 読み込んだデータのサイズに合わせてストリームバッファは自動的に拡張される
// ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しで読み込みは完了する
reader.Fetch();

// ストリームバッファから string 変数にデータを読み込む
reader >> string; // '\0' までのデータを文字列として取得する  string = "abcd"
reader >> string; // 次の '\0' までを取得する                 string = "efgh"
reader >> string; // 末尾までを取得する                       string = "ijkl"
reader >> string; // 末尾までを取得する                       string = 空

// ファイル読み込み用文字列ストリームを解放する
reader.Release();

// ファイルを閉じる
file.Close();

17.2.1.2. 文字列ストリームへの文字列クラスの書き込み

文字列ストリームWriteSFXAnsiString / WriteSFXWideString 関数やインサータ(<< 演算子)を利用して、 SFXAnsiString / SFXWideString 文字列をストリームに書き込んだ場合、文字列の末尾に '\0' は挿入されません。

[Caution] バイナリストリームに文字列を書き込む場合

バイナリストリームに文字列を書き込む場合は、 文字列の末尾に '\0' が自動的に挿入されます。

文字列ストリームに '\0' を書き込むには、 以下のサンプルコードにあるようにストリームに "ends" を書き込みます。

例 17.3. '\0' を書き込む方法

writer << ends; // ストリームに '\0' を書き込む
[Tip] '\0' セパレータ
ストリーム内で文字列を区切るセパレータである '\0' は、 AChar 型文字列(SFXAnsiString)の場合は 1 バイト、 WChar 型文字列(SFXWideString)の場合は 2 バイトです。

例 17.4. 文字列ストリームへの文字列クラスの書き込み

// *** 以下のコードでは、エラー処理が省略されています。 
SFXFile file;                            // ファイル
SFXAnsiStringStreamWriter writer;        // ファイル書き込み用文字列ストリーム
SFXAnsiString string("abcd");  // 書き込む文字列

// 読み書きモードでファイルを開く
file.OpenReadWrite(SFXPath("/dir/data.txt"));

// ファイル書き込み用文字列ストリームを取得する
// ※ size 引数を指定していないのでストリームバッファは可変長
file.GetStreamWriter(&writer);

// ストリームバッファにデータを書き込む
// ※ 書き込んだデータのサイズに合わせてストリームバッファは自動的に拡張される
writer << string; // "abcd" を書き込む
writer << "efgh"; // "efgh" を書き込む
writer << string; // "abcd" を書き込む

// ストリームバッファからファイルにデータを書き込む
// ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する
writer.Flush();

// ファイル書き込み用文字列ストリームを解放する
writer.Release();

// ファイルを閉じる
file.Close();

例 17.5. 書き込まれた文字列: "/dir/data.txt"

61 62 63 64 65 66 67 68 61 62 63 64  // HEX 形式(16 進数表示)

17.2.2. 文字列ストリームを利用したバッファクラスの読み書き

Read 関数や Write 関数の引数に SFXBuffer インスタンスを指定することで、 SFXBuffer 型のデータをストレージに読み書きできます。

[Caution] 注意
文字列ストリームでは、 インサータ(<< 演算子) やエクストラクタ(>> 演算子) の右オペランドに SFXBuffer インスタンスは指定できません。 しかし、バイナリストリームでは指定できます。

17.2.2.1. 文字列ストリームからバッファクラスへの読み込み

SFXBuffer 型変数にデータを読み込む場合は、 予めその変数のサイズを指定する必要があります。 変数のメモリ領域は自動的に確保されません。

[Note] 文字列クラスに読み込む場合

SFXAnsiString / SFXWideString 型変数に読み込む場合は、 予めその変数のサイズを指定する必要はありません。

変数のメモリ領域は、 読み込んだ文字列の長さに合わせて自動的に確保されます。

[Caution] 注意
設定したサイズより少ないデータしか読み込めない場合は、 エラーになります。

例 17.6. 読み込む文字列: "/dir/data.txt"

61 62 63 64 65 66 67 68 61 62 63  // HEX 形式(16 進数表示)

例 17.7. 文字列ストリームからバッファクラスへの読み込み

// *** 以下のコードでは、エラー処理が省略されています。 
SFXFile file;                      // ファイル
SFXAnsiStringStreamReader reader;  // ファイル読み込み用文字列ストリーム
SFXBuffer buffer;  // 読み込むバッファ
buffer.SetSize(4); // あらかじめ読み込むサイズを設定しておく必要がある

// 読み込みモードでファイルを開く
file.OpenReadOnly(SFXPath("/dir/data.txt"));

// ファイル読み込み用文字列ストリームを取得する
// ※ size 引数を指定していないのでストリームバッファは可変長
file.GetStreamReader(&reader);

// ファイルからストリームバッファにデータを読み込む
// ※1. 読み込んだデータのサイズに合わせてストリームバッファは自動的に拡張される
// ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しで読み込みは完了する
reader.Fetch();

// ストリームバッファから buffer 変数にデータを読み込む
// ※ エクストラクタ(>> 演算子)は利用できない
reader.Read(&buffer);   // 最初の 4 バイトを取得する  buffer には 61 62 63 64 (HEX 形式)が格納される
reader.Read(&buffer);   // 次の 4 バイトを取得する    buffer には 65 66 67 68 (HEX 形式)が格納される

// この時点でストリームバッファに残っているデータは 3 バイト
// buffer のサイズは 4 バイトなので読み込もうとするデータの方がストリームバッファに残っているデータよりも大きい
reader.Read(&buffer);  // このとき、ストリームから読み込もうとしても buffer の内容は 65 66 67 68 (HEX 形式) のままで変化しない
                   // SFERR_FAILED が返る

// ファイル読み込み用文字列ストリームを解放する
reader.Release();

// ファイルを閉じる
file.Close();

17.2.2.2. 文字列ストリームへのバッファクラスの書き込み

例 17.8. 文字列ストリームへのバッファクラスの書き込み

// *** 以下のコードでは、エラー処理が省略されています。 
SFXFile file;                                   // ファイル
SFXAnsiStringStreamWriter writer;               // ファイル書き込み用文字列ストリーム
SFXBuffer buffer;                               // バッファ
AChar data[] = {0x61, 0x62, 0x63, 0x64, 0x65};  // バッファに設定するデータ

buffer.Set(data, 5);  // buffer に 5 バイトのデータを設定する

// 読み書きモードでファイルを開く
file.OpenReadWrite(SFXPath("/dir/data.txt"));

// ファイル書き込み用文字列ストリームを取得する
// ※ size 引数を指定していないのでストリームバッファは可変長
file.GetStreamWriter(&writer);

// buffer 変数からストリームバッファにデータを書き込む
// ※ インサータ(<< 演算子)は利用できない
writer.Write(buffer); // 5 バイトの buffer データをファイル書き込み用文字列ストリームに書き込む
writer.Write(buffer); // 5 バイトの buffer データをファイル書き込み用文字列ストリームに書き込む

// ストリームバッファからファイルにデータを書き込む
// ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する
writer.Flush();

// ファイル書き込み用文字列ストリームを解放する
writer.Release();

// ファイルを閉じる
file.Close();

例 17.9. 書き込まれたバイナリ列: "/dir/data.txt"

61 62 63 64 65 61 62 63 64 65  // HEX 形式(16 進数表示)