内存映射文件

合集下载

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

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

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

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

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

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

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

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

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

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

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

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

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

内存映射⽂件(专门读写⼤⽂件)引⾔ ⽂件操作是应⽤程序最为基本的功能之⼀,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. 注意事项•内存映射文件使用较多的内存资源,需注意管理内存的使用情况,避免内存泄漏等问题。

文件内存映射原理

文件内存映射原理

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

mmap原理

mmap原理

mmap原理Mmap原理。

Mmap是一种内存映射文件的技术,它允许文件被映射到进程的地址空间,使得文件可以直接在内存中进行读写操作。

在Unix和类Unix系统中,mmap是一种常见的系统调用,它为程序员提供了一种方便、高效的文件访问方式。

本文将介绍mmap的原理及其在实际应用中的一些常见用法。

一、内存映射文件的基本原理。

内存映射文件是通过将文件映射到进程的虚拟内存空间来实现的。

当一个文件被映射到进程的地址空间后,进程就可以像访问内存一样访问文件,而不需要通过read和write等系统调用来进行读写操作。

这样做的好处是可以减少系统调用的次数,提高文件访问的效率。

在内存映射文件的实现中,操作系统会为文件映射到进程的地址空间中的一段连续的虚拟内存区域,这段虚拟内存区域可以是文件的整个内容,也可以是文件的部分内容。

当程序访问这段虚拟内存区域时,操作系统会根据程序的访问行为来进行相应的处理,比如将文件的内容加载到内存中,或者将内存中的内容写回到文件中。

二、mmap的常见用法。

1. 读取文件内容。

使用mmap可以方便地将文件映射到进程的地址空间中,从而可以直接通过指针来访问文件的内容。

这种方式相比于传统的read系统调用来说,可以减少数据在内核空间和用户空间之间的拷贝次数,提高了文件读取的效率。

2. 修改文件内容。

通过mmap映射文件后,程序可以直接修改文件在内存中的内容,而不需要通过write系统调用来进行写操作。

这种方式可以减少系统调用的次数,提高了文件写入的效率。

3. 共享内存。

除了映射文件外,mmap还可以用来创建共享内存区域,使得不同的进程可以共享同一段内存空间。

这种方式可以方便进程之间进行通信和数据共享。

三、mmap的注意事项。

1. 内存保护。

在使用mmap映射文件时,需要注意对映射内存区域的保护。

可以通过设置内存保护标志来限制对映射内存区域的访问权限,比如只读、可写、执行等。

2. 文件同步。

在使用mmap修改文件内容时,需要注意文件同步的问题。

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

内存映射文件:
内存映射文件有三种,第一种是可执行文件的映射,第二种是数据文件的映射,第三种是借助页面交换文件的内存映射.应用程序本身可以使用后两种内存映射.
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()返回一个文件的句柄),非常方便.。

相关文档
最新文档