Creating a File Mapping Object

创建一个文件映射对象

映射一个文件的第一步是通过调用CreateFile函数来打开一个文件。为了确保其他的进程不能对文件已经被映射的那一部分进行写操作,你应该以唯一访问(exclusive access)的方式来打开文件。另外,文件句柄应该被保留打开直到进程不在需要文件映射对象。一个获取唯一访问的简单方式把CreateFile的fdwShareMode参数设为0.CreateFile所返回的文件句柄,被CreateFileMapping函数用于创建文件映射对象。

CreateFileMapping函数返回文件映射对象的句柄。当创建文件视图时这个句柄会被使用,以便你可以访问共享内存。但你调用CreateFileMapping时,你明确了对象的名字、映射到文件的字节数、以及对映射内存的读写权限。第一个调用CreateFileMapping函数的进程创建文件映射对象。为已经存在的对象调用CreateFileMapping的进程会接受一个已经存在对象的句柄。你可以通过GetLastError函数,了解CreateFileMapping是否成功调用或打开文件映射对象。GetLastError对于创建对象的进程返回NO_ERROR,对于随后的进程返回ERROR_ALREADY_EXITS.

CreateFileMapping函数会失败,如果访问标志(access flag)与CreateFile中所声明的相矛盾。比如读写文件:

  • CreateFile中fdwAccess设为GENERIC_READGENERIC_WRITE
  • CreateFileMapping中fdwProtect设为AGE_READWRITE

创建内存映射对象并不会占用物理内存,它只是保留该块内存。

文件映射的大小

文件映射对象的大小和被映射的文件的大小是独立的。然而,如果文件映射对象比文件大,系统在CreateFileMapping返回时扩大原始文件。如果文件映射对象的大小小于文件,系统只会映射文件申明的字节数。

CreateFileMapping的dwMaximum和dwMaximum参数允许你申明映射到文件的字节数:

  • 当你不希望文件的大小被改变时(比如,映射一个只读文件),调用CreateFileMapping并dwMaximumSizeHigh和dwmaximumSizeLow都置为0.这样做可以创建一个和文件一模一样大小的文件映射对象。否则,你必须计算预估最终文件的大小,因为文件映射对象大小是恒定的,一旦被创建,尺寸就不能增加或减少。尝试映射长度为0的文件会失败并返回失败码ERROR_FILE_INVALID。程序应该测试文件的长度是否为0并拒绝这样的文件。
  • 被一个有名字的文件所支持的文件映射对象的大小被磁盘空间所限制。一个文件视图的大小被限制在未被预留的虚拟内存最大可用连续块的大小。也就是说,最多是2GB除去虚拟内存已经为进程预留的大小空间。

你所选择的文件映射对象的大小控制着在内存映射中,你能看到文件多远的部分。如果你创建了一个500KB的文件映射对象,你只能访问文件前500KB的内容,不管文件有多大。既然创建一个更大的文件映射对象不会花费你任何系统资源,即使你不希望看到整个文件,也可以创建一个和文件一样大的文件映射对象。系统资源的开销来自于创建视图和访问它们。

如果你想要看到的那一部分并不从文件的开头开始,你必须创建一个文件映射对象。这个对象的尺寸是你想要看到的文件部分的大小加上文件的偏移。

 

posted @ 2017-03-07 14:52  ~不倦  阅读(436)  评论(0编辑  收藏  举报