第一次学习内存映射文件

刚开始看,有些概念不太明白。再接再励

 

基本概念

 

内存映射文件
 
内存映射文件正是解决本地多个进程间数据共享的最有效方法。内存映射文件保留了一个地址空间区域,在需要时提交到物理存储器。它们之间的不同点是内存映射文件提交到物理存储器的数据来自磁盘上相应的文件,而不是系统页文件。一旦文件被映射,就可以认为整个文件被加载到内存中,可以像访问内存一样访问文件的内容。
使用内存映射文件的3个目的:
(1)            系统使用内存映射文件来加载和执行.exe和dll文件。这极大的节省了系统页文件空间,也缩短了启动应用程序所需的时间。
(2)            使用内存映射文件访问磁盘上的数据。这既避免了对文件执行文件I/O(输入/输出)操作,也避免了为文件的内容申请缓冲区。
(3)            使用内存映射文件在多个进程间共享数据。Windows也提供了其他进行间通讯的方法-但是这些方法都是使用内存映射文件实现的。
内存映射文件相关函数
CreateFileMapping、OpenFileMapping、MapViewOfFile、UnmapViewOfFile和FlushViewOfFile。
使用内存映射文件分为两步,一步使用CreateFileMapping创建一个内存映射文件内核对象,告诉OS内存映射文件需要的物理内存的大小,该步决定了内存映射文件的用途――究竟是为磁盘上的文件建立内存映射还是为多个进程共享数据建立共享内存。
使用CreateFileMapping函数可以创建或打开一个命名的或未命名的映射文件对象。如果创建的是共享内存,其他进程不能再使用CreateFileMapping函数去创建同名的内存映射文件对象,而要使用OpenFileMapping函数去打开已创建好的对象。使用内存映射文件的第二步是映射文件对象的全部或者一部分到进程的地址空间。可以认为该操作是为文件中的内容分配线性地址空间,并将线性地址和文件内容对应起来。完成这项操作的函数是MapViewOfFile。如果映射成功,函数返回映射视图的内存址址。当不使用内存映射文件时,可以通过UnmapViewOfFile函数撤销映射并使用CloseHandle函数关闭内存映射文件的句柄 。

 如下是代码:

/*
    将结构体写入文件,使用内存映射文件方式将数据读取
*/
#include "windows.h"
#include "stdio.h"
#include "io.h"
#include "fcntl.h"
#include "string.h"
#include "stdlib.h"

typedef struct testData
{
 char szName[16];
 int  iHashValue;
}TestData;

TestData stTestData;

//准备数据写入文件中
int writeDataToFile()
{
 int ifp = -1;
 ifp = _open("c://test.data",_O_CREAT|_O_BINARY|_O_RDWR);
 char tmp[8] = {0};

 for (int i=0; i<30 && ifp != -1; i++)
 {
  strcpy(stTestData.szName,itoa(i,tmp,10));
  stTestData.iHashValue = i;
  _write(ifp,&stTestData,sizeof(stTestData));
 }

 if (ifp != -1)
  _close(ifp);
 ifp = -1;

 return 0;
}

//读取数据显示在界面中
int ReadDataFormFile()
{
 int ifp = -1;
 ifp = _open("c://test.data",_O_BINARY|_O_RDWR);
 while (!eof(ifp))
 {
  _read(ifp,&stTestData,sizeof(stTestData));
  printf("%s/n%d/n-----/n",stTestData.szName,stTestData.iHashValue);
 }

 if (ifp != -1)
  _close(ifp);

 ifp = -1;

 return 0;
}

//使用内存映射文件读取数据
int ReadDataUserMemoryMapping()
{
 //打开要映射的文件
 HANDLE hFile = CreateFile("c://test.data",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  printf("Read file err......");
  return -1;
 }

 //创建内存映射对象
 HANDLE hMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,NULL,NULL,NULL);

 //映射整个BMP文件对内存,返回这块内存的首地址
 LPVOID lpBase = MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);

 TestData arrTestData[3];

 //获得文件中的内容
 for (int i=0; i<10; i++)
 {
  //CopyMemory(&stTestData,(BYTE*)lpBase+sizeof(TestData)*i,sizeof(TestData));
  CopyMemory(arrTestData,(BYTE*)lpBase+sizeof(TestData)*i*3,sizeof(TestData)*3);

  for (int j=0;j<3;j++)
   printf("%s/n%d/n-----/n",arrTestData[j].szName,arrTestData[j].iHashValue);
 }

 UnmapViewOfFile(lpBase);
 CloseHandle(hMap);
 CloseHandle(hFile);

 return 0;
}

//使用内存映射文件将数据读取
int main()
{
 writeDataToFile();
 ReadDataFormFile();

 //
 ReadDataUserMemoryMapping();
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值