天天看点

win32(8)--内存映射

内存映射文件,是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个进程的函数 (CreateFileMapping)。通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。通过内存映射文件,文件内的数据就可以用内存读/写指令来访问,而不是用ReadFile和WriteFile这样的I/O系统函数,从而提高了文件存取速度。

内存映射文件是由一个文件到进程地址空间的映射。Win32中,每个进程有自己的地址空间,一个进程不能轻易地访问另一个进程地址空间中的数据。Win32系统允许多个进程(运行在同一计算机上)使用内存映射文件来共享数据。实际上,其他共享和传送数据的技术,诸如使用SendMessage或者PostMessage,都在内部使用了内存映射文件。看起来很简单的事情,实际上有很多问题要解决,比如文件很大,没有足够的内存全部装进去怎么办。利用内存映射文件确实可以认为操作系统已经为您把文件全部装入了内存,然后只要移动文件指针进行读写即可了。这样就不需要调用那些分配、释放内存块和文件输入/输出的API函数,运用内存映射文件实际上没有涉及实际的文件操作,它更象为每个进程保留一个看得见的内存空间。

CreateFileMapping:创建文件映射

HANDLE WINAPI CreateFileMapping(

HANDLE hFile, //文件句柄(若创建内存页面文件的映射,设为INVALID_HANDLE_VALUE)

LPSECURITY_ATTRIBUTES lpAttributes, //安全属性,NULL为默认

DWORD  flProtect, //页面访问方式,见下表

DWORD  dwMaximumSizeHigh, //尺寸高32位

DWORD  dwMaximumSizeLow, //尺寸低32位

LPCTSTR  lpName ); //映射对象名称

MapViewOfFile:获得映射视图

LPVOID WINAPI MapViewOfFile( //返回的是内存地址的指针,失败返回NULL

_In_ HANDLE hFileMappingObject,//文件映射对象句柄

_In_ DWORD dwDesiredAccess,    //访问模式

_In_ DWORD dwFileOffsetHigh,   //文件偏移高32位

_In_ DWORD dwFileOffsetLow,    //文件偏移低32位

_In_ SIZE_T dwNumberOfBytesToMap);//映射的字节数

参数:dwDesiredAccess访问模式:

FILE_MAP_ALL_ACCESS、FILE_MAP_COPY、FILE_MAP_READ、FILE_MAP_WRITE,都可以和FILE_MAP_EXECUTE同时使用。

CopyMemory:内存复制函数

void CopyMemory(

_In_       PVOID  Destination, //目标地址

_In_ const VOID   *Source, //源地址

_In_       SIZE_T Length); //字节数

UnmapViewOfFile:卸载映射

BOOL WINAPI UnmapViewOfFile( _In_ LPCVOID lpBaseAddress );

OpenFileMapping:用对象名称打开内存映射对象

HANDLE WINAPI OpenFileMappingW(

_In_ DWORD dwDesiredAccess, //访问模式,FILE_MAP_ALL_ACCESS等等

_In_ BOOL bInheritHandle, //是否继承,一般FALSE

_In_ LPCWSTR lpName ); //前面创建的对象名称

操作次序

打开/创建文件CreateFile

创建文件映射CreateFileMapping

获得映射视图MapViewOfFile

读/写数据

卸载映射、关闭内存映射文件、关闭文件,UnmapViewOfFile、CloseHandle