次の方法で共有


IStream - 複合ファイルの実装

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

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

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

Note

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

 

使用すべきとき

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

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

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

Note

コンピューターのメモリ内のヒープより大きいストリーム オブジェクトを作成し、グローバル メモリ オブジェクトに対して 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