2

メモリマップトファイルを使用する場合、読み取り専用または書き込み専用のいずれかであるように見えます。これは、あなたができないことを意味します:

  • 1つを書き込み用に開いて、後でそれを保存しないことを決定します
  • 読んで開いて、後でそれを保存することにしました

このアプリケーションは、書き込み可能なメモリマップファイルを使用してデータファイルを保存しますが、ユーザーは変更を保存せずに終了したい場合があるため、ユーザーが実際に編集する一時ファイルを使用する必要があります。ユーザーが変更を保存することを選択すると、元のファイルが一時ファイルで上書きされるため、最新の変更が適用されます。ファイルが非常に大きくなる可能性があり(> 1GB)、ファイルのコピーに長い時間がかかるため、これは面倒です。

ファイルマッピングの作成に使用されるフラグの多くの組み合わせを試しましたが、オンデマンドで保存する柔軟性を可能にするものはないようです。誰かがこれが事実であることを確認できますか?このアプリケーションはDelphiで記述されていますが、この場合、標準のWindowsAPIを使用してマッピングを作成します。

FMapHandle := CreateFileMapping(FFileHandle, nil, PAGE_READWRITE, 0, 2 * 65536, nil);
FBasePointer := MapViewOfFile(FileMapHandle, FILE_MAP_WRITE, FileOffsetHigh,
FileOffsetLow, NumBytes);
4

2 に答える 2

5

私はあなたができるとは思わない。つまり、あなたはできるかもしれませんが、それは私には意味がありません:-)

メモリマップトファイルの要点は、実際のファイルへのウィンドウであるということです。ファイルに変更を反映させたくない場合は、データ構造(ベースアドレス、サイズ、データの配列など)の変更をバッチ処理して、保存時に適用する必要があります。

この場合、実際にはメモリマップトファイルは必要ありません。変更するチャンクを読み込んで維持するだけです(マルチユーザーアクセスの可能性がある場合は、最初にファイルをロックします)。

アップデート:

保存時に元のファイルを削除し、一時ファイルの名前を元のファイル名に変更する可能性について考えたことはありますか?これは、1Gのデータを一時的なものから元のデータにコピーするよりもはるかに高速である可能性があります。そうすれば、保存したくない場合は、一時ファイルを削除して元のファイルを保持するだけです。

ロード時に元のデータを一時ファイルにコピーする必要がありますが、一時データをコピーして戻す必要はありません(保存するかどうかに関係なく)。これにより、時間が半分になります。

于 2009-10-27T08:05:09.640 に答える
3

可能ですが、重要です。

メモリマップトの基本と、メモリマップトファイルの3つのモードの違いを理解する必要があります。どちらも仮想アドレス空間の一部を確保し、内部テーブルにマッピングエントリを作成します。最初は物理RAMは割り当てられていません。したがって、メモリにアクセスしようとすると、CPUに障害が発生し、OSを修正する必要があります。これは、ファイルの内容をRAMにコピーし、障害のあるアドレスでRAMをプロセスにマッピングすることによって行われます。

ここで、3つのモードの違いは、マップされたページで記述子がどのように設定されるかです。すべての場合において、ページへの読み取りアクセス権を取得します。(最初のモード)。ただし、書き込みアクセスを要求してから書き込みを行うと、最初の書き込みでページが書き込み可能でダーティとしてマークされます。その後、OSの裁量で元のファイルに書き戻すことができます(第2モード)。最後に、コピーオンライトのセマンティクスを取得することができます。それでも、メモリ内のページへの読み取りアクセスのみから始めます。あなたがそれに書き込むとき、CPUはまだ故障していて、OSはそれを修正する必要があります。コピーオンライトでは、その修正は、変更されたページのバッキングストアを元のマップされたファイルではなくページファイルに設定することによって行われます。

したがって、あなたの場合、コピーオンライトモードを使用したいと思います。ユーザーが変更を破棄することにした場合、問題はありません。メモリマッピングを破棄するだけです。メモリ内で変更され、ページファイルによってバックアップされたすべてのページも破棄されます。

ユーザーが保存することを決定した場合、少し難しいタスクがあります。ここで、ファイルのどの部分が変更されたかを把握する必要があります。これらの変更はメモリにあり、ソースファイルに再適用する必要があります。これは、ページガードを使用して行うことができます。したがって、ユーザーが保存することを決定した場合は、変更されたすべてのページを別のメモリブロックにコピーし、(変更されていない)ファイルを書き込み用に再マップして、変更を適用します。

于 2009-10-30T15:00:16.253 に答える