1.问题阐述
传统上都是用fread()、fwrite()之类的函数来存取文件,而文件映射把部分文件或全部文件映射在process的内存空间中,因此可以像存取内存一样存取文件。
2.实现技巧
下面我们介绍创建文件映射的方法。在介绍CreateFileMapping()函数之前,必须先创建CreateFile()函数和OpenFile()函数打开映射到内存空间的文件,取得文件的句柄。
CreateFileMapping()的函数声明:
HANDLE CreateFileMapping(
HANDLE hFile, //文件的句柄
LPSECURITY_ATTRIBUTES lpAttributes, //与安全有关的设置
DWORD flProtect, //用来决定与view有关的属性
DWORD dwMaximumSizeHigh, //设置映射文件的尺寸
DWORD dwMaximumSizeLow,
LPCTSTR lpName //文件映射对象的名称
);
MapViewOfFile()函数的声明:
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, //文件映射的句柄
DWORD dwDesiredAccess, //此view的属性
DWORD dwFileOffsetHigh, //view文件的起点
DWORD dwFileOffsetLow,
SIZE_T dwNumberOfBytesToMap //映射区的大小
);
3.实例代码
//发送数据
void CTestDlg::OnBnClickedBtnsendinfo()
{
UpdateData(TRUE);
//创建文件映像对象
HANDLE hMapping;
LPSTR StrData;
hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,
0x100,"COMMUNICATION");
if(hMapping==NULL)
{
MessageBox("创建文件映像对象","信息提示",MB_OK);
return;
}
//将文件映射到一个进程的地址空间上
StrData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
if(StrData==NULL)
{
AfxMessageBox("MapViewOfFile() failed.");
MessageBox("文件映射失败","信息提示",MB_OK);
return;
}
//向映射内存写数据
sprintf(StrData,m_StrSendData);
//释放映像内存
UnmapViewOfFile(StrData);
}
//接收数据
void CTestDlg::OnBnClickedBtnreceiveinfo()
{
//创建文件映像对象
HANDLE hMapping;
LPSTR StrData;
hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE,0,
0x100,"COMMUNICATION");
if(hMapping==NULL)
{
MessageBox("创建文件映像对象","信息提示",MB_OK);
return;
}
//将文件映射到一个进程的地址空间上
StrData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
if(StrData==NULL)
{
AfxMessageBox("MapViewOfFile() failed.");
MessageBox("文件映射失败","信息提示",MB_OK);
return;
}
//获取映像内存的数据量
m_StrReceiveData.Format("%s",StrData);
//释放映像内存
UnmapViewOfFile(StrData);
UpdateData(FALSE);
}
4.小结
由于各个process之间是独立的,因此彼此之间无法存取对方的内存空间,这虽然是安全的保护机制,但是如果要两个process之间进行数据交换,那就又有问题了。不过win3又另外提供了一系列的进程通信的机制,帮助process与另外一个process交换数据。