4

他のファイルを組み合わせたり編集したりして大きなファイルを作成するアプリケーションを想像してみてください。たとえば、次のようなアプリケーション。

  • 画像のアーカイブを開きます
  • 一部の画像を追加または置換します
  • 既存の画像の一部を変更します
  • 結果の画像セットを使用して新しいアーカイブを作成します

イメージは任意の順序で追加/置換/変更できるため、実行が終了するまで新しいアーカイブを作成できません。

単純なアプローチはMemoryStream、元のアーカイブ内の各イメージのオブジェクトのセットを作成し、必要に応じてストリームを変更/削除/置換してから、そのセットを新しいアーカイブに書き込むことです。このようなアプローチは、実行速度の点でおそらく最良の結果をもたらすでしょう。

問題は明らかです。ストリームのセットを保持するのに十分なメモリが常にあるとは限りません。

この場合、何をお勧めしますか?

速度をメモリと交換し、ある種の一時的なオフメモリストレージを使用する必要があると思います。でも、何を使うかわかりません。

メモリマップトファイルを使用する必要がありますか?または、それらを作成および削除するための何らかのメカニズムを備えた単純な古い一時ファイルですか?多分何か他のもの?

4

4 に答える 4

2

FileStreamと同じように使用できますMemoryStream。それは本質的に、バッファリングとそのすべてをOSに決定する負担を負わせます。OSは最もよく知っており、ドライバーとハードウェアがキャッシュと微調整の複雑さを処理できるようにします。理解しやすく、プロファイル、プロファイル、プロファイルが簡単なコードを書くだけです。

プロファイリングで必要な場合は、2種類のストリームを組み合わせて、パフォーマンスが高く、見栄えの良いものを作成できます。

于 2012-04-20T12:14:07.320 に答える
2

1つのアプローチは、ファイルとファイルシステム(その大部分)を使用し、ある種のメモリキャッシュまたはマッピングを提供することです。

大量のファイルやサイズの大きいファイルを扱っている場合は、追加のハードウェア、RAMについて話していない限り、それをメモリサイズと実際に一致させることはできません(またはアーカイブ全体をメモリに解凍することはできません)。

具体的には、個人的には...

class MemoryArchive {}  

...これはファイルのフロントを装っており、バックエンドでアーカイブします。

アーカイブをディスクの一時ファイルフォルダに解凍します。ほとんどのunziputilsと同様に、アクセスの「小さな単位」、つまりファイルを処理します。

基本MemoryArchive的にはすべてがメモリ内にあるように動作するため、メモリストリーム(またはオブジェクトレベルでの直接アクセスに使用することを決定したもの)の代わりに、ディスク上の一時ファイルであるファイルストリームにマッピングする必要があります。

また、メモリ内の内容がディスク上のコンテンツと同期されていることを確認し、「統合」を維持する必要があるため、同期(および/またはエラー、問題)を処理するための堅牢な方法があります。

その時点で(そしてシステムの性質などに応じて)、主要なタスクは、データベース管理システムに似始めた場所であるファイルシステムストレージの周りにある種のトランザクションをコーディングする必要があるかもしれません。しかし、それはもう一方の「スケールの端」にあるでしょう-そしてあなたがそれなしで生きることができて、それを単純に保つことができれば、それはそれほど問題ではないかもしれません。

ただのアイデアですが、それはすべてあなたの特定の詳細に依存します-
つまり、物事の規模(それは大きく異なる可能性があります-つまり、メモリが特定の場合にロードできる場合、そして処理が十分に速い場合)、どのように小さな変化'アーカイブ内とアーカイブの大きさ、変更の頻度と性質。

最も簡単なケースでは、一時ファイルとして保存し、必要に応じて小さな増分変更を処理することになります。

そして、ある種のものを持っているMemoryArchiveと、将来に向けて物事を取り巻くことができます。そのため、それを変更したり、アーカイブのサイズなどに基づいていくつかのアプローチを組み合わせたりすることができます。実際、これらのシナリオでは、通常、いくつかの「アプローチの組み合わせ」が最適です。さまざまなファイルやサイズを処理する場合、「1つですべてに対応する」ソリューションを作成することはほとんどできないためです。

お役に立てれば、

于 2012-04-20T12:56:26.873 に答える
2

まず、 LOHでの.netの制限に注意してください。基本的に、LOHオブジェクトではメモリが最適化されないため、多数の大きなオブジェクトを連続して作成および破棄すると、「おそらく」「メモリ不足の例外」が発生します。断片化されたメモリホールでは、十分な大きさの連続したメモリスペースが得られない可能性があるため(.net 4.5以降では、これがある程度最適化されていますが、問題は解決しません)。したがって、質問に答えるには、ボックスのアーキテクチャに大きく依存します。RAMが十分にある64ビットであり、ファイルがLOHの問題にぴったり合うことがわかっている場合は、メモリ内オブジェクトを使用してください。 Michaelは、ファイルストリームのスラッシングを実行することを提案しました。

于 2012-04-20T13:01:13.667 に答える
1

メモリマップトファイルを使用する必要がありますか?

それは確かに頭に浮かぶ最初のことでしょう。このアプローチの唯一の問題は、ファイルサイズがマップされたすべてのスペースを消費してしまうかどうかです。

于 2012-04-20T12:14:37.127 に答える