6

物理メモリのスナップショット(VMware VMEMファイルなど)を処理するアプリケーションがあります。特に、物理アドレスではなく仮想アドレスによってスナップショットからプロセス/モジュールを読み取ることができます。これには、ページテーブルを介して一度に4KBのモジュールを再構築することが含まれます。これは、StreamのSeek()メソッドへの多くの呼び出しを意味します。

理由はわかりませんが、これらのSeek()の呼び出しは、物事を劇的に妨げます。結果として、私はそれらを回避する方法、または少なくとも、マネージドSeek()実装を回避する方法を探しています。私の最善の推測は、SetFilePointerをPInvokeして直接操作することですが、そのためには、ストリームのIntPtr/SafeFileHandleを取得する必要があります。いくつかの制限があります:

  1. 私が使用しているAPIは.NET3.5に制限されているため、残念ながらMemoryMappedFileはオプションではありません。

  2. FileStream(リフレクションでアクセスできるプライベートSafeFileHandleフィールドがすでにある)またはPInvoke CreateFile()を使用して、スナップショットを別の方法で取得することはできません。APIには、スナップショットを排他的にロックするBinaryReaderが含まれています。

もちろん、FileStreamとは異なり、BinaryReaderもその基礎となるStreamもファイルハンドルへの参照を持っていません。しかし、確かに1つは存在する必要がありますか?その場合、どうすれば入手できますか?

4

2 に答える 2

4

Stream抽象クラスなのでファイルハンドルはありません。実装するクラスStreamは、ファイル ハンドルを使用する場合と使用しない場合があります -- ファイルFileStreamからデータを読み取るので使用しますがMemoryStream、たとえば、使用しません。

が である の基になるファイル ハンドル (この場合は a SafeFileHandle)BinaryReaderを取得するにStreamは、次のようFileStreamにリフレクションを使用して にアクセスしますprivate SafeFileHandle _handle

SafeFileHandle sfh = (SafeFileHandle)typeof(FileStream).GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue((FileStream)YOUR_BINARY_READER.BaseStream)

余談ですが、この場合、直接電話をかけSetFilePointer()たり、MemoryMappedFile助けたりすることはありません。私が使用しているボリューム (数百万回の連続呼び出し) でランダム ディスク アクセスを処理する高速な方法はないようです。

于 2012-01-01T01:24:15.990 に答える