Share via


IStream - 複合ファイルの実装

IStream インターフェイスは、ストリーム オブジェクトへのデータの読み取りと書き込みをサポートしています。 構造化ストレージ オブジェクトでは、ストリーム オブジェクトにデータが含まれており、ストレージは構造体を提供します。 単純なデータはストリームに直接書き込むことができますが、より頻繁には、ストリームはストレージ オブジェクト内に入れ子になった要素です。 これらは標準ファイルに似ています。

IStream の仕様では、COM 実装でサポートされる機能よりも多くの機能が定義されています。 たとえば、 IStream インターフェイスは、64 ビットシーク ポインターを必要とする最大 2⁶⁴ バイトのストリームを定義します。 ただし、COM 実装では最大 2 ² バイトのストリーム (4 GB) のみがサポートされ、読み取り操作と書き込み操作は常に一度に 2 ² バイトに制限されます。 COM 実装では、ストリーム トランザクションまたはリージョン ロックもサポートされていません。

グローバル メモリに基づいて単純なストリームを作成するには、API 関数 CreateStreamOnHGlobal を呼び出して IStream ポインターを取得します。 複合ファイル オブジェクト内で IStream ポインターを取得するには、 StgCreateDocfile または StgOpenStorage を呼び出します。 これらの関数は IStorage ポインターを取得し、IStreamポインターに対して CreateStream または OpenStream を呼び出すことができます。 どちらの場合も、同じ IStream 実装コードが使用されます。

注意

構造化ストレージの複合ファイルの実装は、ISequentialStreamQueryInterface メソッドでは成功しませんが、IStream インターフェイス ポインターを介した Read メソッドと Write メソッドが含まれています。

 

使用するタイミング

IStream のメソッドを呼び出して、ストリームに対するデータの読み取りと書き込みを行います。

ストリーム オブジェクトは他のプロセスにマーシャリングできるため、アプリケーションはグローバル メモリを使用しなくてもストレージ オブジェクト内のデータを共有できます。 ストリーム オブジェクトの COM 複合ファイル実装では、COM のカスタム マーシャリング機能により、2 つのプロセスが共有メモリ アクセスを持つ場合に、新しいプロセスで元のオブジェクトのリモート バージョンが作成されます。 したがって、リモート バージョンは、その機能を実行するために元のプロセスと通信する必要はありません。

ストリーム オブジェクトのリモート バージョンは、元のストリームと同じシーク ポインターを共有します。 シーク ポインターを共有しない場合は、 IStream::Clone メソッドを使用して、リモート プロセスのストリーム オブジェクトのコピーを提供します。

注意

コンピューターのメモリ内のヒープより大きいストリーム オブジェクトを作成し、グローバル メモリ オブジェクトへの HGLOBAL ハンドルを使用している場合、ストリーム オブジェクトは GlobalRealloc メソッドを内部的に呼び出し、より多くのメモリを必要とします。 GlobalRealloc は常にソースからコピー先にデータをコピーするため、ストリーム オブジェクトを 20 MB から 25 MB に増やすには、大量の時間が必要です。 これは、コピーされた増分のサイズが原因で、ディスクスワップのためにコンピューターに 45 MB 未満のメモリがある場合は悪化します。

推奨される解決策は、GlobalAlloc ではなく VirtualAlloc によって割り当てられたメモリを使用する IStream メソッド実装することです。 これにより、仮想アドレス空間の大きなチャンクを予約し、必要に応じてそのアドレス空間内のメモリをコミットできます。 データのコピーは行われず、メモリは必要なときにのみコミットされます。

GlobalRealloc の代わりに、ストリーム オブジェクトで IStream::SetSize メソッドを呼び出して、事前にメモリ割り当てを増やします。 ただし、これは、上記のように VirtualAlloc を使用するほど効率的ではありません。

 

メソッド

ISequentialStream::Read

現在のシーク ポインターから始めて、指定したバイト数をストリーム オブジェクトからメモリに読み取ります。 この実装では、読み取り中にストリームの末尾に達した場合、S_OKが返されます。 (これは、MS-DOS FAT ファイル システムで見つかった "ファイルの終了" 動作と同じです。

ISequentialStream::Write

現在のシーク ポインターから始まるストリーム オブジェクトに、指定した数をバイトから書き込みます。 この実装では、ストリーム オブジェクトはスパースではありません。 フィル バイトは最終的にディスクに割り当てられ、ストリームに割り当てられます。

IStream::Seek

シーク ポインターの位置を新しい位置に変更します。新しい位置は、ストリームの先頭、ストリームの終端、または現在のシーク ポインターを基準とする相対的な位置です。

IStream::SetSize

ストリーム オブジェクトのサイズを変更します。 この実装では、割り当てられた領域が連続する保証はありません。

IStream::CopyTo

ストリームの現在のシーク ポインターから別のストリームの現在のシーク ポインターに、指定したバイト数をコピーします。

IStream::Commit

IStream の複合ファイルの実装では、トランザクション モードではなく、直接モードでのみストリームを開く機能がサポートされています。 したがって、 メソッドは、すべてのメモリ バッファーを次のストレージ レベルにフラッシュする以外の呼び出し時には影響しません。

この実装では、変更をストリームにコミットしても問題ではなく、ストレージ オブジェクトの変更のみをコミットする必要があります。

IStream::Revert

この実装では、トランザクション ストリームはサポートされていないため、このメソッドの呼び出しは無効です。

IStream::LockRegion

この実装では範囲ロックはサポートされていないため、このメソッドの呼び出しは無効です。

IStream::UnlockRegion

IStream::LockRegion で以前に制限されていたバイト範囲のアクセス制限を削除します。

IStream::Stat

このストリームの STATSTG 構造体を取得します

IStream::Clone

元のストリームと同じバイトを参照する独自のシーク ポインターを持つ新しいストリーム オブジェクトを作成します。

簡易モード の IStream には、次の制約があります。

  • ストリームは、簡易モード ストレージから作成または開かれた場合に単純モードです。 ストレージは、 grfMode パラメーターに STGM_SIMPLE フラグが設定された状態で作成または開かれた場合、単純モードです。
  • Clone メソッドと CopyTo メソッドはサポートされていません。
  • Stat メソッドはサポートされていますが、STATFLAG_NONAME値を指定する必要があります。

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage