首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

1.4  文件的内存映射

文件的内存映射的主要用途有两方面,第一是用来在多个进程之间共享数据,第二是直接用内存映射文件来访问磁盘上的数据文件,无需再进行文件的I/0操作。进程间共享数据有很多种方法,稍后将对这些技术进行介绍。内存映射文件的使用可以分为以下三步:

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

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

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

1.4.1  内存映射API函数

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

l           

HANDLE CreateFileMapping(

    HANDLE hFile,

    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,

    DWORD flProtect,

    DWORD dwMaximumSizeHigh,

    DWORD dwMaximumSizeLow,

    LPCTSTR lpName

    ); 

l           

其中参数含义如下所述。

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

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

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

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

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

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

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

l           

LPVOID MapViewOfFile(

    HANDLE hFileMappingObject,

    DWORD dwDesiredAccess,

    DWORD dwFileOffsetHigh,

    DWORD dwFileOffsetLow,

    DWORD dwNumberOfBytesToMap

    );

l           

其中参数含义如下所述。

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

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

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

dwNumberOfBytesToMap:为映射视图的大小。

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

l           

LPVOID MapViewOfFileEx(

    HANDLE hFileMappingObject, 

    DWORD dwDesiredAccess,

    DWORD dwFileOffsetHigh,

    DWORD dwFileOffsetLow,

    DWORD dwNumberOfBytesToMap,

    LPVOID lpBaseAddress

    );

l           

其中参数lpBaseAddress指定映射视图的实际内存地址。其他参数与MapViewOfFile()函数中的相同。

在完成对映射到进程地址空间区域的文件处理后,需要通过函数UnmapViewOfFile()完成对文件数据映射的释放,该函数原型为:

l           

BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);

l           

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

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论