1

MyClass単一のファイルへのアクセスを提供することがすべてです。CheckHeader()、、、など ReadSomeData()である必要があります。UpdateHeader(WithInfo)

ただし、このクラスが表すファイルは非常に複雑であるため、特別な設計上の考慮事項が必要です。

そのファイルには、さまざまなノードタイプを持つ潜在的に巨大なフォルダのようなツリー構造が含まれており、断片化をより適切に処理するためにブロック/セルベースです。サイズは通常20MB未満です。それは私のデザインではありません。

そのようなクラスをどのように設計しますか?

  • 〜20MBのストリームをメモリに読み込みますか?
  • 一時ディレクトリにコピーを置き、そのパスをプロパティとして保持しますか?

  • 大きなもののコピーをメモリに保存し、読み取り専用プロパティとして公開しますか?
  • GetThings()例外をスローするコードを含むファイルから?

このクラスは最初は私だけが使用しますが、十分に終了すればオープンソース化するかもしれません。

(これは設計に関する質問ですが、プラットフォームは.NETであり、クラスはXPのオフラインレジストリアクセスに関するものです)

4

2 に答える 2

3

これは、このデータをどのように処理する必要があるかによって異なります。線形に1回だけ処理する必要がある場合は、メモリ内の大きなファイルのパフォーマンスヒットを取得する方が速い場合があります。

ただし、単一の線形解析以外にファイルでさまざまなことを行う必要がある場合は、データをSQLiteなどの軽量データベースに解析してから操作します。このようにして、ファイルのすべての構造が保持され、ファイルに対する後続のすべての操作が高速になります。

于 2010-09-05T01:18:30.100 に答える
1

レジストリへのアクセスは非常に複雑です。あなたは基本的に大きな二分木を読んでいます。クラスの設計は、保存されているデータ構造に大きく依存する必要があります。そうして初めて、適切なクラス設計を選択できます。柔軟性を維持するには、REG_SZ、REG_EXPAND_SZ、DWORD、SubKeyなどのプリミティブをモデル化する必要があります。DonSymeの著書Expert F#には、バイナリコンビネータを使用したバイナリ解析に関する優れたセクションがあります。基本的な考え方は、オブジェクトがバイナリ表現から逆シリアル化する方法を自分で知っているということです。このように構成されたバイトのストリームがある場合

<Header> <Node1 />
<Node2> <Directory1>
</ Node2> </ Header>

BinaryReaderから始めて、バイナリオブジェクトをバイトごとに読み取ります。最初のものはヘッダーでなければならないことがわかっているので、それをHeaderオブジェクトに渡すことができます

public class Header
{
   static Header Deserialize(BinaryReader reader)
   {
      Header header = new Header();

      int magic = reader.ReadByte();
      if( magic == 0xf4 ) // we have a node entry
         header.Insert(Node.Read( reader );
      else if( magic == 0xf3 ) // directory entry
         header.Insert(DirectoryEntry.Read(reader))
      else 
         throw NotSupportedException("Invalid data");

      return header;
   }
}

パフォーマンスを維持するために、たとえば、このインスタンスまたはそのインスタンスの特定のプロパティが実際にアクセスされるまで、データの解析を遅らせることができます。

Windowsのレジストリは非常に大きくなる可能性があるため、一度に完全にメモリに読み込むことはできません。チャンクする必要があります。Windowsが適用する1つの解決策は、ファイル全体が数ギガバイトにまたがることができるページプールメモリに割り当てられますが、実際にアクセスされた部分のみがディスクからメモリにスワップアウトされることです。これにより、Windowsは非常に大きなレジストリファイルを効率的に処理できます。読者にも似たようなものが必要になります。遅延解析は1つの側面であり、間にデータを読み取る必要なしにファイル内をジャンプする機能は、パフォーマンスを維持するために非常に重要です。

ページングプールとレジストリの詳細については、http: //blogs.technet.com/b/markrussinovich/archive/2009/03/26/3211216.aspxを参照してください。

Apiの設計は、効率を維持するためにデータを読み取る方法によって異なります(たとえば、メモリマップトファイルを使用して、異なるマップされた領域から読み取る)。.NET 4では、メモリマップトファイルの実装が登場しました。これは非常に優れていますが、OSAPIのラッパーも存在します。

あなたの、アロイス・クラウス

メモリマップトファイルからの遅延ロードをサポートするには、バイト配列をオブジェクトに読み込んで後で解析するのではなく、さらに一歩進んで、メモリマップトファイルからのメモリチャンクのオフセットと長さのみを格納するのが理にかなっています。後でオブジェクトに実際にアクセスしたときに、データを読み取って逆シリアル化できます。このようにして、ファイル全体をトラバースし、オフセットとメモリマップトファイルへの参照のみを含むオブジェクトのツリーを構築できます。これにより、大量のメモリを節約できます。

于 2010-09-08T22:21:50.210 に答える