映射文件的第一步是调用CreateFile函数来打开这个文件。为了确保被映射的文件不能被其他的进程写入,你应该使用专门的权限打开这个文件。另外,文件句柄要一直打开,直到进程不再需要它。一个得到专门的权限的简单方法是,将CreateFile的fdwShareMode参数设置为零。CreateFileMapping函数使用CreateFile函数返回的句柄来创建一个文件映射对象。
CreateFileMapping函数给文件映射对象返回一个句柄。当创建文件视图的时候会用到这个句柄,使得你可以访问共享的内存。当你调用CreateFileMapping函数时,你要指定一个对象名,从文件中映射多少字节,以及映射内存的读写许可。第一个调用CreateFileMapping函数的进程会创建一个文件映射对象。如果文件影响已经存在,进程调用CreateFileMapping函数函数会的到这个文件映像对象的句柄。调用GetLastError函数,你就可以知道调用CreateFileMapping函数来创建或者打开一个文件映射对象是否成功了。GetLastError给创建的进程返回NO_ERROR,给之后的进程返回ERROR_ALREADY_EXISTS。
如果CreateFileMapping函数中的权限标志和CreateFile函数中的权限标志不一致,则会执行失败。举个例子,读写一个文件:
1、给CreateFile函数的fdwAccess参数附GENERIC_READ和GENERIC_WRITE。
2、给CreateFileMapping函数的fdwProtect参数附PAGE_READWRITE。
创建一个文件映射对象并不开辟物理内存,只是预定。
文件映射大小
文件映射对象的大小和映射的文件大小没有关系。但是,如果文件映射对象比文件要大,系统会在CreateFileMapping返回之前,扩大文件。如果文件映射对象比文件小,系统只从文件中映射指定的字节数。
CreateFileMapping函数dwMaximumSizeHigh和dwMaximumSizeLow参数是你可以指定从文件中映射的字节数:
1、如果你确实不想改变文件的大小(比如,映射一个只读文件时),调用CreateFileMapping函数并将dwMaximumSizeHigh和dwMaximumSizeLow参数设置为零。这样一来,文件映射对象的大小和文件的大小是一致的。否则,你应该估算一下已经完成的文件的大小,因为文件映射对象的大小是固定的;一旦被建立,他们的大小就不能被增大或减小。如果用这样的方式来映射一个长度为零的文件会引起ERROR_FILE_INVALID错误。程序应该检验文件的长度,并且拒绝长度为零的文件:
2、以文件支持的文件映射对象的大小是受磁盘大小限制的。文件视图的大小,受最大的、未被预约的连续虚拟内存限制。这最多是2G减去进程已经预约的虚拟内存。
你选择的文件映射大小,控制了你利用内存映射能“看到”的文件的范围。如果你创建了一个500Kb大小的文件映射对象,不管文件有多大,你只可以访问文件的前500Kb。既然创建更大的文件映射对象不会消耗系统资源,建立和文件一样大的映射对象(将CreateFileMapping的dwMaximumSizeHigh和dwMaximumSizeLow参数设置为零),及时你不需要查看整个文件。当创建文件视图以及访问他们的时候,才会消耗系统资源。
加入你想要访问的部分不是从文件开头开始的,你就必须建立一个文件映射对象。对象的大小是你想要访问的那一部分的大小加上它在文件中的偏移量。