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

文档说了两件事。

首先(在“备注”部分),

如果应用程序为文件映射对象指定的大小大于磁盘上实际命名文件的大小,并且如果页面保护允许写访问(即flProtect参数指定PAGE_READWRITEor PAGE_EXECUTE_READWRITE),则磁盘上的文件增加到匹配指定大小的文件映射对象。如果文件被扩展,文件老端和新端之间的文件内容不保证为零;行为由文件系统定义。

这基本上意味着当您将磁盘上的文件映射到比调用 to 的文件更大的内存区域时,磁盘上的文件会被调整大小CreateFileMapping(),并用未指定的内容填充它。

其次(在“返回值”部分),

如果对象在函数调用之前存在,则函数返回现有对象的句柄(具有其当前大小,而不是指定的大小),并GetLastError返回ERROR_ALREADY_EXISTS.

对我来说,这意味着如果您的文件已经映射,您的调用resize_file()将无效。您必须取消映射,调用resize_file(),然后重新映射它,这可能是您想要的,也可能不是。

于 2013-01-15T15:00:18.567 回答