文件的内存映射小结(一)

来源:互联网 发布:威斯布鲁克身体数据 编辑:程序博客网 时间:2024/05/22 00:51
一、内存映射文件的使用
        内存映射文件的使用可以分为以下三步:

(1)用CreateFileMapping()创建一个文件映射内核对象;

(2)用MapViewOfFile()将文件数据映射到进程的地址空间;

(3)用UnmapViewOfFile()从进程地址空间解除这个映射。

二、内存映射API函数

在进行内存映射文件时,首先要用到的是CreateFileMapping()函数,其原型为:

HANDLE CreateFileMapping(

    HANDLE hFile,

    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,

    DWORD flProtect,

    DWORD dwMaximumSizeHigh,

    DWORD dwMaximumSizeLow,

    LPCTSTR lpName

    );

其中参数含义如下所述。

hFile:指定待映射到进程地址空间的文件句柄,例如,可以由CreateFile()函数的返回值获取该句柄。如果需要创建一个与文件无关的内存映射, 可以将它设置成为0xFFFFFFFF(INVALID_HANDLE_VALUE)或者取为–1

lpFileMappingAttributes:一个指向SECURITY_ATTRIBUTES结构的指针,它指明返回的句柄是否可以被子进程所继承。另外,在SECURITY_ATTRIBUTES结构中,也包括一个安全性描述的子指针。

flProtect:允许指定内存块的访问权限,权限值有PAGE_READONLY、PAGE_ READWRITE和PAGE_WRITECOPY,PAGE_WRITECOPY。

dwMaximumSizeHigh和dwMaximumSizeLow  指定了文件的最大字节数,由于这两个参数共64位,因此所支持的最大文件长度为16GB,几乎可以满足任何大数据量文件处理的要求

lpName:内存映射对象指定名字,通过调用CreateFileMapping()函数和Open- FileMapping()函数,其他进程可用这个名字来访问相同的文件映射。

在调用CreateFileMapping()时,可以用GetLastError()来检查其返回的错误信息。如果返回值为ERROR_ALREADY_EXISTS,则表示内存映射对象指定名字已经存在。有关其他返回值的意义见MSDN的详细说明。

一 旦某个内存映射对象由CreateFileMapping()创建成功,就可以调用MapView-OfFile()函数把文件视图映射到进程地址空间上,这个函数需要使用一个由CreateFileMapping()函数或 OpenFileMapping()函数返回的句柄,并允许指定访问模式和映射的字节数,以及文件映射对象中的偏移量。MapViewOfFile()函 数的原型为:

LPVOID MapViewOfFile(

    HANDLE hFileMappingObject,

    DWORD dwDesiredAccess,

    DWORD dwFileOffsetHigh,

    DWORD dwFileOffsetLow,

    DWORD dwNumberOfBytesToMap

    );

其中参数含义如下所述。

hFileMappingObject:为CreateFileMapping()返回的文件映射对象句柄。

dwDesiredAccess:再次指定了对文件数据的访问方式,而且同样要与CreateFile- Mapping()函数所设置的保护属性相匹配。

dwFileOffsetHigh和dwFileOffsetLow:分别为文件偏移的高32位和低32位。

dwNumberOfBytesToMap:为映射视图的大小。

另外,还可以使用MapViewOfFileEx()函数来实现同样的功能,此函数还允许调用进程为映射视图指定特殊的内存地址,但是如果指定的内存地址空间大小不够,则函数执行失败。MapViewOfFileEx()函数的原型为:

LPVOID MapViewOfFileEx(

    HANDLE hFileMappingObject, 

    DWORD dwDesiredAccess,

    DWORD dwFileOffsetHigh,

    DWORD dwFileOffsetLow,

    DWORD dwNumberOfBytesToMap,

    LPVOID lpBaseAddress

    );

其中参数lpBaseAddress指定映射视图的实际内存地址。其他参数与MapViewOfFile()函数中的相同。
         在完成对映射到进程地址空间区域的文件处理后,需要通过函数UnmapViewOfFile()完成对文件数据映射的释放
,该函数原型为:

BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);

        其 中参数lpBaseAddress为MapViewOfFile()函数的返回值。在使用了MapViewOfFile()函数之后,必须要有对应的 UnmapViewOfFile()函数调用,否则在进程终止之前,保留的区域将无法释放。除此之外,在进程终止之前还必须要用CloseHandle ()将文件句柄­­­­­­释放,否则将会出现资源泄漏的问题。