8

重複の可能性:
メモリ マップト ファイルを動的に拡張する方法

こんにちは、私は Windows のメモリ マップト ファイルに格納されているツリー状のデータ構造を持っています。レコードを挿入する必要があるときは、空きポインタがファイルの終わりに近いかどうかを確認しています。しかし、本当の問題はファイルのサイズを変更することです。

Windows のドキュメントでは、`CreateFileMapping' はそのパラメータに従ってファイルのサイズを変更すると書かれています。というわけで以下のように使うことにしました。

#define SEC_IMAGE_NO_EXECUTE 0x11000000

static void resize_file(wchar_t * file_name,int size)
{
  hFile = CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,0,\
                     NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,\
                        NULL);
  if (hFile == INVALID_HANDLE_VALUE)
  {
       MessageBox(NULL,L"resize_file CreateFile have been failed", szAppName,MB_OK);
      exit(0);
  }

  // open file mapping object //
  HANDLE hMap = CreateFileMapping(hFile,NULL,PAGE_EXECUTE_READWRITE|SEC_IMAGE_NO_EXECUTE,0,size,NULL);

  // Close files and mapping //
  CloseHandle(hMap); 
  CloseHandle(hFile);
}

これは機能しますか?ファイルを開いて再マップしただけで、フラッシュしなかったため、これについて少し罪悪感があります。それをフラッシュして、他の操作も行う必要がありますか?

4

1 に答える 1

13

ドキュメントには2つのことが書かれています。

まず(「備考」欄)、

アプリケーションがディスク上の実際の名前付きファイルのサイズよりも大きいファイル マッピング オブジェクトのサイズを指定した場合、およびページ保護が書き込みアクセスを許可している場合 (つまり、flProtectパラメータでPAGE_READWRITEまたはが指定されている場合PAGE_EXECUTE_READWRITE)、ディスク上のファイルはファイル マッピング オブジェクトの指定されたサイズと一致します。ファイルが拡張されている場合、ファイルの古い終わりとファイルの新しい終わりの間のファイルの内容はゼロであるとは限りません。動作はファイル システムによって定義されます。

これは基本的に、 への呼び出しでファイルよりも大きなメモリ領域にマップすると、ディスク上のファイルのサイズが変更CreateFileMapping()され、指定されていないものでいっぱいになることを意味します。

次に (「戻り値」セクション)、

関数呼び出しの前にオブジェクトが存在する場合、関数は既存のオブジェクトへのハンドルを (指定されたサイズではなく現在のサイズで) 返し、 をGetLastError返しますERROR_ALREADY_EXISTS

私にとって、これはresize_file()、ファイルが既にマップされている場合、への呼び出しは効果がないことを意味します。マップを解除し、 を呼び出してからresize_file()、再マップする必要があります。これは、必要な場合とそうでない場合があります。

于 2013-01-15T15:00:18.567 に答える