30

次の要件を解決するために C# を使用しました。 - 大量のデータを高速に受信できるアプリを作成する - 受信したデータをさらに受信しながら分析できる必要があります。- CPU とディスクの使用を最小限に抑える

アルゴリズムの私のアイデアは..

SIZE = 10MB
Create a mmf with the size of SIZE
On data recived:
  if data can't fit mmf: increase mmf.size by SIZE
  write the data to mmf

-> 以前の「部屋/スペース」を使用すると、ディスクのサイズが 10MB 単位で増加します。

「mmf.sizeをSIZEで増やす」はC#でどのように行われますか? mmfs とビューの作成に関する多くの簡単な例を見つけましたが、実際に mmfs 領域を増やすコードを見た唯一の場所 (リンク) は、コンパイルできないコードを使用しています。どんな助けでも大いに感謝します。

編集これにより例外が発生します:

private void IncreaseFileSize()
{
    int theNewMax = this.currentMax + INCREMENT_SIZE;
    this.currentMax = theNewMax;

    this.mmf.Dispose();

    this.mmf = MemoryMappedFile.CreateFromFile(this.FileName, FileMode.Create, "MyMMF", theNewMax);
    this.view = mmf.CreateViewAccessor(0, theNewMax);            
}

この例外がスローされます: 別のプロセスで使用されているため、プロセスはファイル 'C:\Users\moberg\Documents\data.bin' にアクセスできません。

4

5 に答える 5

28

ファイルをメモリにマップすると、そのサイズを増やすことはできません。これは、メモリ マップ ファイルの既知の制限です。

...ファイル マッピング オブジェクトのサイズは静的であるため、完成したファイルのサイズを計算または見積もる必要があります。一度作成すると、サイズを増減することはできません。

1 つの戦略は、特定のサイズ、たとえば 1GB または 2GBの非永続メモリ マップ ファイルに格納されたチャンクを使用することです。これらは、独自の設計の最上位レベルViewAccessorで管理します (おそらく から必要なメソッドの基本的なパススルーを実行しますMemoryMappedViewAccessor)。

編集:または、使用すると予想される最大サイズの非永続メモリ マップ ファイルを作成し (たとえば、アプリケーションの起動時に調整するパラメーターを使用して 8GB を開始する)、MemoryMappedViewAccessor論理チャンクごとに を取得することもできます。非永続ファイルは、各ビューが要求されるまで物理リソースを使用しません。

于 2011-05-23T14:50:08.803 に答える
1

コードがコンパイルされない理由は、存在しないオーバーロードを使用しているためです。自分でファイルストリームを作成し、それを正しいオーバーロードに渡します (2000 が新しいサイズになると仮定します)。

FileStream fs = new FileStream("C:\MyFile.dat", FileMode.Open);
MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "someName", 2000,
 MemoryMappedFileAccess.ReadWriteExecute, null, HandleInheritablity.None, false);

または、次のオーバーロードを使用して、フィルストリームの作成をスキップします。

MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("C:\MyFile.dat", 
          FileMode.Open, "someName", 2000);
于 2011-05-23T12:38:38.100 に答える
1

I found that closing and recreating the mmf with the same name but new size works to all intents and purposes

                using (var mmf = MemoryMappedFile.CreateOrOpen(SenderMapName, 1))
                {
                    mmf.SafeMemoryMappedFileHandle.Close();
                }
                using (var sender = MemoryMappedFile.CreateNew(SenderMapName, bytes.Length))

and it's really fast.

于 2019-02-27T01:14:46.207 に答える
0

MemoryMappedFile.CreateFromFileパラメータをとるのオーバーロードを使用しcapacityます。

于 2011-05-23T12:26:01.877 に答える