CreateFileMapping的参数解释,
句柄:
若hFile是一个文件的句柄,那么是
基于文件系统的命名文件创建文件映射对象。文件打开时的存取权限必需与flProtect兼容。当该文件映射对象映射到某进程的地址空间时,文件视图存取权限dwDesiredAccess应与fProtect兼容。
若hFile为0xFFFFFFFF(INALID_HANDLE_VALUE),说明是要
基于系统页文件创建文件映射对象,此时
必需要指明文件映射对象的大小
dwMaximumSizeHigh,dwMaximumSizeLow.
对象名称:
如果对象的名称已存在,则在CreateFileMapping创建后获
得仅仅是已存在的文件映射对象句柄,而且其本身大小不会因前面的指定而改变。这也是共享文件映射对象的一种方式。
下面防止文件映射对象已存在的做法,存在时让其失败。
hMap = CreateFileMapping(...);
if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMap);
hMap = NULL;
}
return hMap;
文件大小:
当基于命名文件创建file-mapping object时,若大小为0,则说该file-mapping object的maximum大小等于当前文件的大小。
若为
file-mapping object
指定的大小大于磁盘文件的实际大小,磁盘上的文件将增长以适合
file-mapping
对象的大小。若文件不能增长,file-mapping的创建将失败。
通常磁盘文件的大小不能超过file-mapping对象的大小,若超过,则并不是所有的文件内容可以共享(因为没有全部映射)
共享文件映射对象:
当file-mapping创建后,可以通过
句柄复制或对象的名称在进程间共享。
基于内存(系统页文件)文件映射对象的共享是进程间通信的一种方式(进程间发送数据
WM_COPYDATA
就是通过这种方式实现的)
.通过对象的名字打开file-mapping对象的方法:
OpenFileMapping
可惜这种方法不适用于
Wince(后面将说明其共享方式).若存在指定名字的file-mapping对象并且该对象的安全描述符与OpenFileMapping所指定的存取权限不冲突,就可以打开file-mapping获取其句柄。
(在关闭相应的文件映射对象之前,
用于创建该对象的文件句柄不应该用于任何读写操作
I/O,
以免冲突
)
(创建好文件映射对象只是提供了映射一个文件视图的可能并没有将文件的视图映射到进程的地址空间。应使用MapViewOfFile完成此步操作)
关闭文件映射对象:
为了完全关闭一个file-mapping对象,
应用程序必需解除该对象的所有映射
(UnmapViewOfile).
然后关闭其句柄。二者的调用顺序没有关系。但
UnmapViewOfFile
是必须被调用的。下面要讨论其原因:内核对象本身有个使用计数,
CloseHandle
只是把使用计数减一。当使用计数为
0
时内核对象关闭。而
file-mapping
对象的映射视图内部维护着该对象的句柄(
open handle
)
.
所以必须调用
UnmapViewOfile
关闭句柄。
File-mapping
对象在其所有的打开句柄关闭后关闭。
在wince下使用CreateFileMapping,
第一个参数
hFile
必需是通过
CreateFileForMapping
创建的,这也是
wince
特有的一个函数。它是一个的特殊版本
CreateFile
函数
,
用于文件映射对象的创建。它通过在系统内核地址空间的回调函数来创建该文件,让内核创建该文件的目的是为了保证该文件也适用于其他进程而不仅仅是其创建进程。若你的进程退出时没有关闭由CreateFileForMapping所返回的句柄,此句柄会由内核关闭。
不应
CreateFileForMapping
去打开一个文件多次,这样做只是浪费内存,而且有可能导致他们映射对象间的不一致。若要多个应用程序共享一个文件,只须其中一个应用程序调用
CreateFileForMapping,
再调用
CreateFilemapping
创建并命名其文件内核对象
.
其它应用程序可以通过
CreateFileMapping
,使用
NVALID_HANDLE_VALUE
作为文件句柄并使用前面应用程序创建的文件内核对象的名字获得已创建的文件内核对象的句柄。这也是在
weince
下文件内核对象的共享方法。这样做的好处,可以节约内核并且不会引起多个应用程序打开同一文件所引起的冲突状况。
下面是示列:
HANDLE hFile = NULL, hFileMap = NULL;
PBYTE pFileData;
hFile = CreateFileForMapping(m_fileName, GENERIC_READ,
FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_RANDOM_ACCESS,0);
hFileMap = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, 0);//文件映射对象的大小等于文件的大小。
pFileData = (PBYTE)MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, 0);//全部映射
HANDLE hMemMap=NULL;
PBYTE pMemData;
hMemMap = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, memSize, 0);//创建基于系统页文件的内存映射对象。
//这也是进程间共享数据的方法。
pMemData = (PBYTE)MapViewOfFile (hMemMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);