SophiaFramework UNIVERSE 5.3 |
バイナリストリームは、バイナリ列(任意の型のデータ)を読み書きするためのストリームです。 下記の表にあるように、読み書きのタイプに応じて 2 種類のバイナリストリームが存在します。
例 17.11. バイナリストリームからのバイナリ列読み込み
// *** 以下のコードでは、エラー処理が省略されています。 SFXFile file; // ファイル SFXBinaryStreamReader reader; // ファイル読み込み用バイナリストリーム // 読み込みモードでファイルを開く file.OpenReadOnly(SFXPath("/dir/data.txt")); // ファイル読み込み用バイナリストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamReader(&reader); // ファイルからストリームバッファにデータを読み込む // ※1. 読み込んだデータのサイズに合わせてストリームバッファは自動的に拡張される // ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しで読み込みは完了する reader.Fetch(); // バイナリ列をリトルエンディアンとして解釈する reader >> little; UInt32 v; // ストリームバッファから各変数にデータを読み込む reader >> v; // 先頭から 4 バイトを UInt32 として解釈する // リトルエンディアンなので、v に 0x78563412 が代入される // 以降のバイナリ列をビッグエンディアンとして解釈する reader >> big; reader.ReadUInt32(&v); // 次の 4 バイトを UInt32 として解釈する // ビッグエンディアンなので v = 0x11223344 // reader >> v と同じ UInt08 c; reader >> c; // 先頭から 1 バイトを UInt08 として解釈する : c = 0x55 reader.ReadUInt08(&c); // 先頭から 1 バイトを取得しようとするが、末尾まできたので c は変化しない // この関数はエラーを返す // ファイル読み込み用バイナリストリームを解放する reader.Release(); // ファイルを閉じる file.Close();
エクストラクタ(>> 演算子)と Read 系関数の違い | |
---|---|
エクストラクタ(>> 演算子)はエラー値を返しませんが、 Read 系関数はエラー値を返します。 |
例 17.12. バイナリストリームへのバイナリ列書き込み
// *** 以下のコードでは、エラー処理が省略されています。 SFXFile file; // ファイル SFXBinaryStreamWriter writer; // ファイル書き込み用バイナリストリーム // 読み書きモードでファイルを開く file.OpenReadWrite(SFXPath("/dir/data.txt")); // ファイル書き込み用バイナリストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamWriter(&writer); // バイナリ列をリトルエンディアンとして解釈する writer << little; // ストリームバッファに各種データを書き込む // ※ 書き込んだデータのサイズに合わせてストリームバッファは自動的に拡張される writer.WriteUInt08(0x22); // UInt08 として書き込む writer.WriteUInt16(0x22); // UInt16 として書き込む writer.WriteUInt32(0x22); // UInt32 として書き込む // writer << 0x22; は曖昧なのでエラー // writer << static_cast<UInt08>(0x22); なら可 // 以降のバイナリ列をビッグエンディアンとして解釈する writer << big; // ストリームバッファにデータを書き込む // ※ 書き込んだデータのサイズに合わせてストリームバッファは自動的に拡張される writer.WriteUInt32(0x22); // UInt32 として書き込む // ストリームバッファからファイルにデータを書き込む // ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する writer.Flush(); // ファイル書き込み用バイナリストリームを解放する writer.Release(); // ファイルを閉じる file.Close();
インサータ(<< 演算子)と Write 系関数の違い | |
---|---|
インサータ(<< 演算子)はエラー値を返しませんが、 Write 系関数はエラー値を返します。 |
バイナリストリームの ReadSFXAnsiString/ReadSFXWideString 関数や WriteSFXAnsiString/WriteSFXWideString 関数の引数、または インサータ(<< 演算子)やエクストラクタ(>> 演算子) のオペランドに SFXAnsiString / SFXWideString インスタンスを指定することで文字列クラスのデータをストレージに読み書きできます。
バイナリストリームから文字列クラスのデータを読み込む場合、 次の '\0' までのデータを SFXAnsiString / SFXWideString 型変数に読み込みます。
この場合、予めその変数のサイズを指定する必要はありません。 変数のメモリ領域は、 読み込んだ文字列の長さに合わせて自動的に確保されます。
バッファクラスに読み込む場合 | |
---|---|
SFXBuffer 型変数にデータを読み込む場合は、 予めその変数のサイズを指定する必要があります。 変数のメモリ領域は自動的に確保されません。 |
終端までに '\0' が見つからない場合 | |||||
---|---|---|---|---|---|
終端までに '\0' が見つからない場合はエラーとなり、 変数に文字列は格納されません(変数の内容は読み込む前の状態のままです)。 このとき、ReadSFXAnsiString / ReadSFXWideString 関数は SFERR_INVALID_STATE を返しますが、 エクストラクタ(>> 演算子はエラーを返しません。
|
'\0' セパレータ | |
---|---|
ストリーム内で文字列を区切るセパレータである '\0' は、 AChar 型文字列(SFXAnsiString)の場合は 1 バイト、 WChar 型文字列(SFXWideString)の場合は 2 バイトです。 |
例 17.15. バイナリストリームから文字列クラスへの読み込み
// *** 以下のコードでは、エラー処理が省略されています。 SFXFile file; // ファイル SFXBinaryStreamReader 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" // この時点で、残りの末尾までに '\0' がない reader >> string; // このとき、ストリームから読み込もうとしても string = "efgh" のままで変化しない // Read 関数で読み込む場合は SFERR_INVALID_STATE が返る // ファイル読み込み用バイナリストリームを解放する reader.Release(); // ファイルを閉じる file.Close();
バイナリストリームの WriteSFXAnsiString / WriteSFXWideString 関数や、 インサータ(<< 演算子)を利用して、 SFXAnsiString / SFXWideString 文字列をストリームに書き込むと、文字列の末尾に '\0' が自動的に挿入されます。
文字列ストリームの場合 | |
---|---|
文字列ストリームに書き込む場合は、 文字列の末尾に '\0' は挿入されません。 |
'\0' セパレータ | |
---|---|
ストリーム内で文字列を区切るセパレータである '\0' は、 AChar 型文字列(SFXAnsiString)の場合は 1 バイト、 WChar 型文字列(SFXWideString)の場合は 2 バイトです。 |
例 17.16. バイナリストリームへの文字列クラスの書き込み
// *** 以下のコードでは、エラー処理が省略されています。 SFXFile file; // ファイル SFXBinaryStreamWriter writer; // ファイル書き込み用バイナリストリーム SFXAnsiString string("abcd"); // 書き込む文字列 // 読み書きモードでファイルを開く file.OpenReadWrite(SFXPath("/dir/data.txt")); // ファイル書き込み用バイナリストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamWriter(&writer); // string 変数からストリームバッファにデータを書き込む // ※ 書き込んだデータのサイズに合わせてストリームバッファは自動的に拡張される writer << string; // 文字列 "abcd" と '\0' が書き込まれる writer << string; // 文字列 "abcd" と '\0' が書き込まれる // ストリームバッファからファイルにデータを書き込む // ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する writer.Flush(); // ファイル書き込み用バイナリストリームを解放する writer.Release(); // ファイルを閉じる file.Close();
Read 関数や Write 関数の引数、または インサータ(<< 演算子) やエクストラクタ(>> 演算子) のオペランドに SFXBuffer インスタンスを指定することでバッファクラスのデータをストレージに読み書きできます。
注意 | |
---|---|
バイナリストリームでは、 インサータ(<< 演算子) やエクストラクタ(>> 演算子) の右オペランドに SFXBuffer インスタンスを指定できます。 しかし、文字列ストリームでは指定できません。 |
バイナリストリームから SFXBuffer 型変数にデータを読み込む場合は、 予めその変数のサイズを指定する必要があります。 変数のメモリ領域は自動的に確保されません。
文字列クラスに読み込む場合 | |
---|---|
SFXAnsiString / SFXWideString 型変数に読み込む場合は、 予めその変数のサイズを指定する必要はありません。 変数のメモリ領域は、 読み込んだ文字列の長さに合わせて自動的に確保されます。 |
注意 | |
---|---|
設定したサイズより少ないデータしか読み込めない場合は、 エラーになります。 |
例 17.19. バイナリストリームからバッファクラスへの読み込み
// *** 以下のコードでは、エラー処理が省略されています。 *** SFXFile file; // ファイル SFXBinaryStreamReader reader; // ファイル読み込み用バイナリストリーム SFXBuffer buffer; // 読み込むバッファ buffer.SetSize(4); // あらかじめ読み込むサイズを設定しておく必要がある // 読み込みモードでファイルを開く file.OpenReadOnly(SFXPath("/dir/data.txt")); // ファイル読み込み用バイナリストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamReader(&reader); // ファイルからストリームバッファにデータを読み込む // ※1. 読み込んだデータのサイズに合わせてストリームバッファは自動的に拡張される // ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しで読み込みは完了する reader.Fetch(); // ストリームバッファから buffer 変数にデータを読み込む reader >> buffer; // 最初の 4 バイトを取得する buffer には 11 22 33 44 (HEX 形式) が格納される reader >> buffer; // 次の 4 バイトを取得する buffer には 55 11 22 33 (HEX 形式) が格納される // この時点でストリームバッファに残っているデータは 3 バイト // buffer のサイズは 4 バイトなので読み込もうとするデータの方がストリームバッファに残っているデータよりも大きい reader >> buffer; // このとき、ストリームから読み込もうとしても buffer の内容は 55 11 22 33 (HEX 形式) のままで変化しない // Read 関数で読み込む場合は SFERR_FAILED エラーが返る // ファイル読み込み用バイナリストリームを解放する reader.Release(); // ファイルを閉じる file.Close();
例 17.20. バイナリストリームへのバッファクラスの書き込み
// *** 以下のコードでは、エラー処理が省略されています。 SFXFile file; // ファイル SFXBinaryStreamWriter writer; // ファイル書き込み用バイナリストリーム SFXBuffer buffer; // バッファ AChar data[] = {0x11, 0x22, 0x33, 0x44, 0x55}; // バッファに設定するデータ buffer.Set(data, 5); // buffer に 5 バイトのデータを設定する // 読み書きモードでファイルを開く file.OpenReadWrite(SFXPath("/dir/data.txt")); // ファイル書き込み用文字列ストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamWriter(&writer); writer << buffer; // buffer 変数からストリームバッファにデータ(5 バイト)を書き込む writer << buffer; // buffer 変数からストリームバッファにデータ(5 バイト)を書き込む // ストリームバッファからファイルにデータを書き込む // ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する writer.Flush(); // ファイル書き込み用バイナリストリームを解放する writer.Release(); // ファイルを閉じる file.Close();
バイナリストリームは簡易パーサーとして利用できます。
例えば、
// *** 以下のコードでは、エラー処理が省略されています。 SFXBinaryStreamWriter writer; // 出力バイナリストリーム SFXBinaryStreamReader reader; // 入力バイナリストリーム SFXAnsiString data1("ansi string1"); SFXAnsiString data2("ansi string2"); SFXWideString data3("wide string"); SInt32 data4 = -10; UInt16 data5 = 20; Bool data6 = true; SFXBuffer buffer; AChar temp[] = {0x11, 0x22, 0x33, 0x44, 0x55}; buffer.Set(temp, 5);
で、
// 読み書きモードでファイルを開く file.OpenReadWrite(SFXPath("/dir/data.txt")); // ファイル書き込み用ストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamWriter(&writer); // ストリームバッファに各種変数のデータを書き込む // ※ 書き込んだデータのサイズに合わせてストリームバッファは自動的に拡張される writer << data1 << data2 << data3 << data4 << data5 << data6 << buffer; // ストリームバッファからファイルにデータを書き込む // ※ 可変長バッファストリームの場合、1 回の Flush 関数呼び出しで書き込みは完了する writer.Flush(); // ファイル書き込み用ストリームを解放する writer.Release(); // ファイルを閉じる file.Close();
として書き込んだデータは、
buffer.SetSize(5); // 読み込みモードでファイルを開く file.OpenReadOnly(SFXPath("/dir/data.txt")); // ファイル読み込み用ストリームを取得する // ※ size 引数を指定していないのでストリームバッファは可変長 file.GetStreamReader(&reader); // ファイルからストリームバッファにデータを読み込む // ※1. 読み込んだデータのサイズに合わせてストリームバッファは自動的に拡張される // ※2. 可変長バッファストリームの場合、1 回の Fetch 関数呼び出しで読み込みは完了する reader.Fetch(); // ストリームバッファから各種変数にデータを読み込む reader >> data1 >> data2 >> data3 >> data4 >> data5 >> data6 >> buffer; // ファイル読み込み用ストリームを解放する reader.Release(); // ファイルを閉じる file.Close();
として読み込めます。
制約条件 | |
---|---|
簡易パーサーは、書き込むときのデータと読み込むときのデータに関して、 順序と型が一致しなければ正しく動作しません。 また、複数の '\0' を含む文字列についても正しく動作しません。 |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |