内存映射文件

合集下载

内存映射文件的作用功能介绍

内存映射文件的作用功能介绍

内存映射文件的作用功能介绍内存映射文件的主要用途:1.操作大文件 2.进程间大量数据共享,下面分别介绍如下:VC++中使用内存映射文件处理大文件引言文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。

一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。

目前,对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的,本文下面将针对这种Windows核心编程技术展开讨论。

内存映射文件内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。

由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。

另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。

实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。

所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。

内存映射文件

内存映射文件

内存映射文件:内存映射文件有三种,第一种是可执行文件的映射,第二种是数据文件的映射,第三种是借助页面交换文件的内存映射.应用程序本身可以使用后两种内存映射.1.可执行文件映射:Windows在执行一个Win32应用程序时使用的是内存映射文件技术.系统先在进程地址空间的0x00400000以上保留一个足够大的虚拟地址空间(0x00400000以下是由系统管理的),然后把应用程序所在的磁盘空间作为虚拟内存提交到这个保留的地址空间中去(我的理解也就是说,虚拟内存是由物理内存和磁盘上的页面文件组成的,现在应用程序所在的磁盘空间就成了虚拟地址的页面文件).做好这些准备后,系统开始执行这个应用程序,由于这个应用程序的代码不在内存中(在页面文件中),所以在执行第一条指令的时候会产生一个页面错误(页面错误也就是说,系统所访问的数据不在内存中),系统分配一块内存把它映射到0x00400000处,把实际的代码或数据读入其中(系统分配一块内存区域,把它要访问的在页面文件中的数据读入到这块内存中,需在注意是系统读入代码或数据是一页一页读入的),然后可以继续执行了.当以后要访问的数据不在内存中时,就可以通过前面的机制访问数据.对于Win32DLL的映射也是同样,不过DLL文件应该是被Win32进程共享的(我想应该被映射到x80000000以后,因为0x80000000-0xBFFFFFFF是被共享的空间).当系统在另一个进程中执行这个应用程序时,系统知道这个程序已经有了一个实例,程序的代码和数据已被读到内存中,所以系统只需把这块内存在映射到新进程的地址空间即可,这样不就实现了在多个进程间共享数据了吗!然而这种共享数据只是针对只读数据,如果进程改写了其中的代码和数据,操作系统就会把修改的数据所在的页面复制一份到改写的进程中(我的理解也就是说共享的数据没有改变,进程改写的数据只是共享数据的一份拷贝,其它进程在需要共享数据时还是共享没有改写的数据),这样就可以避免多个进程之间的相互干扰.2.数据文件的内存映射:数据文件的内存映射原理与可执行文件内存映射原理一样.先把数据文件的一部分映射到虚拟地址空间的0x80000000 - 0xBFFFFFFF,但没有提交实际内存(也就是说作为页面文件),当有指令要存取这段内存时同样会产生页面错误异常.操作系统捕获到这个异常后,分配一页内存,映射内存到发生异常的位置,然后把要访问的数据读入到这块内存,继续执行刚才产生异常的指令(这里我理解的意思是把刚才产生异常的指令在执行一次,这次由于数据已经映射到内存中,指令就可以顺利执行过去),由上面的分析可知,应用程序访问虚拟地址空间时由操作系统管理数据在读入等内容,应用程序本身不需要调用文件的I/O函数(这点我觉得很重要,也就是为什么使用内存映射文件技术对内存的访问就象是对磁盘上的文件访问一样).3.基于页面交换文件的内存映射:内存映射的第三种情况是基于页面交换文件的.一个Win32进程利用内存映射文件可以在进程共享的地址空间保留一块区域(0x8000000 - 0xBFFFFFFF),这块区域与系统的页面交换文件相联系.我们可以用这块区域来存储临时数据,但更常见的做法是利用这块区域与其他进程通信(因为0x80000000以上是系统空间,进程切换只是私有地址空间,系统空间是所有进程共同使用的),这样多进程间就可以实现通信了.事实上Win32多进程间通信都是使用的内存映射文件技术,如PostMessage(),SentMessage()函数,在内部都使用内存映射文件技术.使用内存映射文件的方法:1.利用内存映射文件进行文件I/O操作:CreateFile()-->CreateFileMapping()-->MapViewOfFile()......2.利用内存映射文件实现Win32进程间通信:我只介绍两种常用的方法:第一种方法:两个进程使用同一个文件映射核心对象,打开各自的视图,或者父进程把自己创建的文件映射核心对象继承给子进程使用.这种方法比较安全有效.第二种方法:基于页面交换文件的内存映射对象.在调用CreateFileMapping()函数时,传递的文件句柄为0xFFFFFFFF,系统就从页面交换文件中提交物理内存,然后进程之间按照第一种方法进程通信.这种方法不用事先准备一个特殊的文件(也就是说不用事先调用CreateFile()返回一个文件的句柄),非常方便.。

内存映射文件(专门读写大文件)

内存映射文件(专门读写大文件)

内存映射⽂件(专门读写⼤⽂件)引⾔ ⽂件操作是应⽤程序最为基本的功能之⼀,Win32 API和MFC均提供有⽀持⽂件处理的函数和类,常⽤的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。

⼀般来说,以上这些函数可以满⾜⼤多数场合的要求,但是对于某些特殊应⽤领域所需要的动辄⼏⼗GB、⼏百GB、乃⾄⼏TB的海量存储,再以通常的⽂件处理⽅法进⾏处理显然是⾏不通的。

⽬前,对于上述这种⼤⽂件的操作⼀般是以内存映射⽂件的⽅式来加以处理的,本⽂下⾯将针对这种Windows核⼼编程技术展开讨论。

内存映射⽂件概述 内存⽂件映射也是Windows的⼀种内存管理⽅法,提供了⼀个统⼀的内存管理特征,使应⽤程序可以通过内存指针对磁盘上的⽂件进⾏访问,其过程就如同对加载了⽂件的内存的访问。

通过⽂件映射这种使磁盘⽂件的全部或部分内容与进程虚拟地址空间的某个区域建⽴映射关联的能⼒,可以直接对被映射的⽂件进⾏访问,⽽不必执⾏⽂件I/O操作也⽆需对⽂件内容进⾏缓冲处理。

内存⽂件映射的这种特性是⾮常适合于⽤来管理⼤尺⼨⽂件的。

在使⽤内存映射⽂件进⾏I/O处理时,系统对数据的传输按页⾯来进⾏。

⾄于内部的所有内存页⾯则是由虚拟内存管理器来负责管理,由其来决定内存页⾯何时被分页到磁盘,哪些页⾯应该被释放以便为其它进程提供空闲空间,以及每个进程可以拥有超出实际分配物理内存之外的多少个页⾯空间等等。

由于虚拟内存管理器是以⼀种统⼀的⽅式来处理所有磁盘I/O的(以页⾯为单位对内存数据进⾏读写),因此这种优化使其有能⼒以⾜够快的速度来处理内存操作。

使⽤内存映射⽂件时所进⾏的任何实际I/O交互都是在内存中进⾏并以标准的内存地址形式来访问。

磁盘的周期性分页也是由操作系统在后台隐蔽实现的,对应⽤程序⽽⾔是完全透明的。

内存映射⽂件的这种特性在进⾏⼤⽂件的磁盘事务操作时将获得很⾼的效益。

快速读取内存文件-内存映射文件的方法

快速读取内存文件-内存映射文件的方法

快速读取内存⽂件-内存映射⽂件的⽅法
1、前⾔
Windows提供了3种进⾏内存管理的⽅法:
• 虚拟内存,最适合⽤来管理⼤型对象或结构数组。

• 内存映射⽂件,最适合⽤来管理⼤型数据流(通常来⾃⽂件)以及在单个计算机上运⾏的多个进程之间共享数据。

• 内存堆栈,最适合⽤来管理⼤量的⼩对象。

内存映射⽂件可以⽤于3个不同的⽬的
• 系统使⽤内存映射⽂件,以便加载和执⾏. exe和DLL⽂件。

这可以⼤⼤节省页⽂件空间和应⽤程序启动运⾏所需的时间。

• 可以使⽤内存映射⽂件来访问磁盘上的数据⽂件。

这使你可以不必对⽂件执⾏I/O操作,并且可以不必对⽂件内容进⾏缓存。

• 可以使⽤内存映射⽂件,使同⼀台计算机上运⾏的多个进程能够相互之间共享数据。

Windows确实提供了其他⼀些⽅法,以便在进程之间进⾏数据通信,但是这些⽅法都是使⽤内存映射⽂件来实现的,这使得内存映射⽂件成为单个计算机上的多个进程互相进⾏通信的最有效的⽅法。

参考博客:。

内存映射文件详解-----C++实现

内存映射文件详解-----C++实现

内存映射⽂件详解-----C++实现先不说内存映射⽂件是什么。

贴个代码先,。

#include <iostream>#include <fcntl.h>#include <io.h>#include <afxwin.h>using namespace std;int main(){//开始//获得⽂件句柄HANDLE hFile=CreateFile("c:\\test.dat", //⽂件名GENERIC_READ|GENERIC_WRITE, //对⽂件进⾏读写操作FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING, //打开已存在⽂件FILE_ATTRIBUTE_NORMAL,0);//返回值size_high,size_low分别表⽰⽂件⼤⼩的⾼32位/低32位DWORD size_low,size_high;size_low= GetFileSize(hFile,&size_high);//创建⽂件的内存映射⽂件。

HANDLE hMapFile=CreateFileMapping(hFile,NULL,PAGE_READWRITE, //对映射⽂件进⾏读写size_high,size_low, //这两个参数共64位,所以⽀持的最⼤⽂件长度为16EBNULL);if(hMapFile==INVALID_HANDLE_VALUE){AfxMessageBox("Can't create file mapping.Error%d:\n", GetLastError());CloseHandle(hFile);return 0;}//把⽂件数据映射到进程的地址空间void* pvFile=MapViewOfFile(hMapFile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);unsigned char *p=(unsigned char*)pvFile;//⾄此,就获得了外部⽂件test.dat在内存地址空间的映射,//下⾯就可以⽤指针p"折磨"这个⽂件了CString s;p[size_low-1]='!';p[size_low-2]='X'; //修改该⽂件的最后两个字节(⽂件⼤⼩<4GB⾼32位为0)s.Format("%s",p);//读⽂件的最后3个字节AfxMessageBox(s);//结束//UnmapViewOfFile(pvFile); //撤销映射//CloseHandle(hFile); //关闭⽂件return 0;}忘⼩了说,只要你把这⼏个API函数搞定了,⼀般的内存映射问题就可以解决了。

内存映射文件与共享内存的区别

内存映射文件与共享内存的区别

内存映射文件与共享内存的区别
内存映射文件和共享内存都是用来实现进程间通信的技术,但它们之间存在着
一些重要的区别。

首先,内存映射文件是将一个文件映射到进程的地址空间中,使得整个文件可以像内存一样被访问,而共享内存则是将一段物理内存映射到多个进程的地址空间中,以实现进程间数据的共享。

其次,内存映射文件是一种将文件内容映射到内存的技术,通过将文件映射到
内存中,可以避免频繁的磁盘IO操作,提高访问文件内容的速度。

而共享内存则
是一段物理内存空间,在不同进程中访问共享内存可以实现进程间的数据共享,比如可以通过共享内存传递数据或共享某些资源。

另外,内存映射文件是一种通过对文件进行映射来实现内存访问的技术,对文
件的修改会实时反映到文件中,但内存映射文件不支持对文件进行完全随机的访问和修改。

而共享内存是一种直接访问物理内存的方式,对共享内存的操作会直接影响到进程间的通信。

此外,内存映射文件更适用于对文件进行读写操作,特别是适合大文件的处理,而共享内存更适用于简单的数据共享,比如进程之间传递一些共享的数据结构或缓冲区。

综上所述,内存映射文件和共享内存都是实现进程间通信的方式,但它们在实
现机制、适用场景和操作方式上存在一些区别。

开发者可以根据具体的需求选择合适的技术来实现进程间通信,提高程序的性能和效率。

内存映射文件原理

内存映射文件原理

内存映射文件原理内存映射文件原理1. 概述•内存映射文件是一种将文件内容映射到内存地址空间的技术。

•它可以让我们像访问内存一样访问文件,提供了快速读写文件的方法。

2. 原理介绍1.内存映射文件通过建立虚拟内存与磁盘文件之间的映射关系实现。

2.当我们将一个文件映射到内存中时,操作系统会为该文件分配一块虚拟内存空间。

3.虚拟内存空间被划分为多个固定大小的页,而文件也被划分为相同大小的页。

4.当访问虚拟内存空间中的某个页时,操作系统会将对应的磁盘页加载到内存中。

5.文件中的数据和内存中的数据是共享的,对内存中的数据的修改会直接写回到文件中。

3. 优点•快速读写:内存映射文件利用了操作系统的虚拟内存机制,可以直接访问文件数据,避免了频繁的磁盘读写操作,提高了读写性能。

•方便操作:将文件映射到内存后,我们可以像操作内存一样访问文件,使用指针访问数据更加方便和高效。

•共享数据:多个进程可以将同一个文件映射到各自的内存空间中,实现共享数据的目的,方便进程间的通信。

4. 使用步骤1.打开文件:使用指定的文件路径打开需要映射的文件。

2.获取文件大小:通过系统调用或API函数获取文件的大小。

3.创建映射对象:使用系统调用或API函数创建一个映射对象,指定文件句柄、大小等信息。

4.映射到内存:将映射对象映射到内存中,得到一个指向映射区域的指针。

5.访问数据:可以通过指针对映射区域中的数据进行读写操作。

6.取消映射:使用系统调用或API函数取消内存与文件的映射关系。

7.关闭文件:使用系统调用或API函数关闭文件。

5. 使用场景•大文件处理:内存映射文件可以有效地处理大文件,减少了磁盘读写的次数,提高了处理效率。

•数据共享:多个进程可以通过内存映射文件实现数据的共享,方便了进程间的通信和数据交换。

•高性能数据库:许多高性能数据库系统使用内存映射文件来提高数据的读写速度和响应时间。

6. 注意事项•内存映射文件使用较多的内存资源,需注意管理内存的使用情况,避免内存泄漏等问题。

文件内存映射原理

文件内存映射原理

文件内存映射原理
文件内存映射是一种将磁盘文件映射到进程地址空间的技术,使得文件在内存中的数据可以像访问内存一样被读取和写入。

文件内存映射可以提供对文件的连续访问和修改,而不需要通过读写函数来操作文件。

文件内存映射的原理是通过调用操作系统提供的函数,将文件映射到进程的虚拟地址空间。

在调用映射函数时,操作系统会在进程的虚拟地址空间中创建一个映射区域,该映射区域与文件的一部分或全部内容相对应。

当映射建立完成后,进程可以像访问内存一样直接读取和写入映射区域的数据。

对映射区域的读写操作会被直接转化为对相应文件位置的读写操作,无需通过系统调用和文件缓冲区的数据拷贝。

文件内存映射的优点是提供了更快的访问速度和简化操作的接口。

由于文件的数据可以直接映射到内存中,所以读取和写入文件数据的速度通常比使用传统的读写函数更快。

此外,文件内存映射也提供了更为简单的编程接口,可以直接对内存数据进行操作,而无需关心底层的文件读写细节。

不过,文件内存映射也有一些注意事项。

首先,文件内存映射通常用于处理较大的文件,因为映射整个文件可能会占用大量的内存空间。

其次,对映射区域的修改并不会立即写入文件,而是在操作系统认为合适的时候进行同步操作。

因此,在对映射区域进行写入操作后,需要通过调用相应的同步函数来确保
数据已经写入文件。

总的来说,文件内存映射是一种高效的文件访问技术,它可以加速对文件数据的读写操作,并简化编程接口。

不过,在使用文件内存映射时需要注意适当控制内存占用和及时同步数据的操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

内存映射文件内存映射文件是由一个文件到一块内存的映射。

Win32提供了允许应用程序把文件映射到一个进程的函数(CreateFileMapping)。

这样,文件内的数据就可以用内存读/写指令来访问,而不是用ReadFile和WriteFile这样的I/O系统函数,从而提高了文件存取速度。

这种函数最适用于需要读取文件并且对文件内包含的信息做语法分析的应用程序,如对输入文件进行语法分析的彩色语法编辑器,编译器等。

把文件映射后进行读和分析,能让应用程序使用内存操作来操纵文件,而不必在文件里来回地读、写、移动文件指针。

有些操作,如放弃“读”一个字符,在以前是相当复杂的,用户需要处理缓冲区的刷新问题。

在引入了映射文件之后,就简单的多了。

应用程序要做的只是使指针减少一个值。

映射文件的另一个重要应用就是用来支持永久命名的共享内存。

要在两个应用程序之间共享内存,可以在一个应用程序中创建一个文件并映射之,然后另一个应用程序可以通过打开和映射此文件把它作为共享的内存来使用。

VC++中使用内存映射文件处理大文件(1)关键词:VC++ 内存映射阅读提示:本文给出了一种方便实用的解决大文件的读取、存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍。

引言文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC 提供的CFile类等。

一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。

目前,对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的,本文下面将针对这种Windows核心编程技术展开讨论。

内存映射文件内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。

由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。

另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。

实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。

所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。

下面给出使用内存映射文件的一般方法:首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。

在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。

为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉系统文件的尺寸以及访问文件的方式。

在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据作为映射到该区域的物理存储器进行提交。

由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分映射到进程地址空间。

此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。

这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、通过CloseHandle()关闭前面创建的文件映射对象和文件对象。

内存映射文件相关函数在使用内存映射文件时,所使用的API函数主要就是前面提到过的那几个函数,下面分别对其进行介绍:HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);函数CreateFile()即使是在普通的文件操作时也经常用来创建、打开文件,在处理内存映射文件时,该函数来创建/打开一个文件内核对象,并将其句柄返回,在调用该函数时需要根据是否需要数据读写和文件的共享方式来设置参数dwDesiredAccess和dwShareMode,错误的参数设置将会导致相应操作时的失败。

HANDLE CreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCTSTR lpName);CreateFileMapping()函数创建一个文件映射内核对象,通过参数hFile指定待映射到进程地址空间的文件句柄(该句柄由CreateFile()函数的返回值获取)。

由于内存映射文件的物理存储器实际是存储于磁盘上的一个文件,而不是从系统的页文件中分配的内存,所以系统不会主动为其保留地址空间区域,也不会自动将文件的存储空间映射到该区域,为了让系统能够确定对页面采取何种保护属性,需要通过参数flProtect来设定,保护属性PAGE_READONLY、PAGE_READWRITE和PAGE_WRITECOPY分别表示文件映射对象被映射后,可以读取、读写文件数据。

在使用PAGE_READONLY时,必须确保CreateFile()采用的是GENERIC_READ参数;PAGE_READWRITE则要求CreateFile()采用的是GENERIC_READ|GENERIC_WRITE参数;至于属性PAGE_WRITECOPY则只需要确保CreateFile()采用了GENERIC_READ和GENERIC_WRITE其中之一即可。

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

LPVOID MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,DWORD dwNumberOfBytesToMap);MapViewOfFile()函数负责把文件数据映射到进程的地址空间,参数hFileMappingObject为CreateFileMapping()返回的文件映像对象句柄。

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

虽然这里一再对保护属性进行重复设置看似多余,但却可以使应用程序能更多的对数据的保护属性实行有效控制。

MapViewOfFile()函数允许全部或部分映射文件,在映射时,需要指定数据文件的偏移地址以及待映射的长度。

其中,文件的偏移地址由DWORD型的参数dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定,而且必须是操作系统的分配粒度的整数倍,对于Windows操作系统,分配粒度固定为64KB。

当然,也可以通过如下代码来动态获取当前操作系统的分配粒度:SYSTEM_INFO sinf;GetSystemInfo(&sinf);DWORD dwAllocationGranularity =sinf.dwAllocationGranularity;参数dwNumberOfBytesToMap指定了数据文件的映射长度,这里需要特别指出的是,对于Windows 9x操作系统,如果MapViewOfFile()无法找到足够大的区域来存放整个文件映射对象,将返回空值(NULL);但是在Windows 2000下,MapViewOfFile()只需要为必要的视图找到足够大的一个区域即可,而无须考虑整个文件映射对象的大小。

在完成对映射到进程地址空间区域的文件处理后,需要通过函数UnmapViewOfFile()完成对文件数据映像的释放,该函数原型声明如下:BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);唯一的参数lpBaseAddress指定了返回区域的基地址,必须将其设定为MapViewOfFile()的返回值。

在使用了函数MapViewOfFile()之后,必须要有对应的UnmapViewOfFile()调用,否则在进程终止之前,保留的区域将无法释放。

除此之外,前面还曾由CreateFile()和CreateFileMapping()函数创建过文件内核对象和文件映射内核对象,在进程终止之前有必要通过CloseHandle()将其释放,否则将会出现资源泄漏的问题。

除了前面这些必须的API函数之外,在使用内存映射文件时还要根据情况来选用其他一些辅助函数。

例如,在使用内存映射文件时,为了提高速度,系统将文件的数据页面进行高速缓存,而且在处理文件映射视图时不立即更新文件的磁盘映像。

为解决这个问题可以考虑使用FlushViewOfFile()函数,该函数强制系统将修改过的数据部分或全部重新写入磁盘映像,从而可以确保所有的数据更新能及时保存到磁盘。

用内存映射文件处理大文件应用示例下面结合一个具体的实例来进一步讲述内存映射文件的使用方法。

相关文档
最新文档