表示: Delphi C++
表示設定

ストリームを使ってデータの読み書きを行う

提供:RAD Studio XE2
移動: 案内, 検索

ストリームの使用 への移動

RTL の利用:インデックス への移動

どのストリームクラスにも,データを読み書きするための共通のメソッドがいくつかあります。これらのメソッドは,以下の観点で分類されています。

  • 読み出された,または書き込まれたバイト数を返すかどうか
  • バイト数を知る必要があるかどうか
  • エラー時に例外を生成するかどうか

目次

読み書きをするためのストリームメソッド

Read メソッドは,指定されたバイト数だけ現在位置からバッファへと読み出します。その後,実際に読み出したバイト数だけ読み書き位置を進めます。Read のプロトタイプは,以下のとおりです。

 function Read(var Buffer; Count: Longint): Longint;

Read は,ファイルのバイト数が不明な場合などに使用すると便利です。Read は実際に転送されたバイト数を返すからです。現在位置を超えるデータが Count バイト数に満たない場合は,実際に転送されるバイト数は Count より小さくなります。

Write メソッドは,バッファからストリームへと現在位置から Count バイト分書き込みます。Write のプロトタイプは,以下のとおりです。

 function Write(const Buffer; Count: Longint): Longint;

書き込み後,Write により,実際に書き込めたバイト数だけ読み書き位置を進め,関数の戻り値とします。バッファの終端に到達した場合,あるいはストリームがこれ以上のバイト数を受け付けられない場合は,書き込んだバイト数は Count より小さいことがあります。

上記関数と類似した手続きとして ReadBufferWriteBuffer があります。これらは,ReadWrite とは異なり,読み出されたバイト数や書き込まれたバイト数を返しません。構造体から読み出しをする場合のように,必要なバイト数があらかじめわかっている場合に,これらの手続きは有効です。バイト数を正確に一致させることができない場合,ReadBufferWriteBuffer は,例外(EReadErrorEWriteError)を生成します。この点が ReadWrite メソッドと明確に違います。Read と Write は,要求値とのバイト数の差を返すことができます。ReadBufferWriteBuffer のプロトタイプは,次のようになります。

 procedure ReadBuffer(var Buffer; Count: Longint);
 procedure WriteBuffer(const Buffer; Count: Longint);

これらのメソッドは,実際の読み出しや書き込みは Read メソッドと Write メソッドを呼び出すことで実行します。

コンポーネントの読み出しと書き込み

TStream には,コンポーネントの読み書きを行う専用メソッド(ReadComponentWriteComponent)が定義されています。アプリケーションでこれらのメソッドを使用すると,アプリケーションを作成したり実行時に変更したとき,コンポーネントとそのプロパティを保存できます。

IDE は,この ReadComponent メソッドと WriteComponent メソッドを使ってフォームファイルとの間でコンポーネントの読み書きをします。フォームファイルとの間でコンポーネントを読み書きするとき,ストリームクラスは TFiler クラス,TReader,および TWriter と一緒に動作して,オブジェクトをフォームファイルから読み出したりディスクへ出力します。コンポーネントストリームシステムの使い方については,System.Classes.TStreamSystem.Classes.TFilerSystem.Classes.TReaderSystem.Classes.TWriter,および System.Classes.TComponent の各クラスを参照してください。

文字列の読み出しと書き込み

読み出しや書き込みの関数に文字列を渡す場合は,正しい構文を知る必要があります。読み出しルーチンと書き込みのルーチンの Buffer パラメータは,それぞれ var 型と const 型です。これらは型のないパラメータなので,ルーチンはこれらの型として渡された変数のアドレスをとります。

文字列の処理の際に最も一般に使用される型は,長い文字列です。ただし,長い文字列を Buffer パラメータとして渡すと,正しい結果を生成できません。長い文字列には,文字列中にサイズ,参照カウント,および文字へのポインタが入っています。そのため,長い文字列の逆参照はポインタ要素に対する結果にはなりません。正しい結果を得るには,文字列を Pointer または PChar にキャストしてから逆参照する必要があります。次に例を示します。

 procedure caststring;
 var
   fs: TFileStream;
 const
   s: string = 'Hello';
 begin
   fs := TFileStream.Create('temp.txt', fmCreate or fmOpenWrite);
   fs.Write(s, Length(s));// 無意味なデータが生じる
   fs.Write(PChar(s)^, Length(s));// これが正しい方法
 end;


関連項目

以前のバージョン
他言語版