使用内存映射文件必须执行下列操作步骤
1.创建或打开一个文件内核对象,该对象用于标识你想用作内存映射文件的文件
2.创建一个文件映射内核对象,告诉系统该文件的大小和你打算该如何访问该文件
3.让系统将文件映射对象的一部分或全部映射到你进程的地址空间
4.当完成对内存映射文件的使用时,需要撤销映射到你的进程的地址空间中的文件
5.关闭文件映射内核对象
6,.关闭文件内核对象
下面介绍一下每步使用的函数
1.HANDLE CreateFile(
LPCTSTR lpFileName, // 文件名称
DWORD dwDesiredAccess, // 访问权限
DWORD dwShareMode, // 共享方式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性
DWORD dwCreationDisposition, // 创建方式create
DWORD dwFlagsAndAttributes, // 标志和属性attributes
HANDLE hTemplateFile // 按照这个句柄模板创建新文件
);
在这里我想介绍的是dwDesiredAccess和dwShareMode
dwDesiredAccess:
0:不能读取或写入,当只想获取文件属性时,请设定0
GENERIC_READ :可以从文件中读取内容
GENERIC_WRITE:可以向文件中写入内容
GENERIC_READ|GENERIC_WRITE:可以读取或向文件写入内容
dwShareMode:
0:打开文件的任何尝试均失败
FILE_SHARE_READ:其他程序试图使用GENERIC_WRITE打开文件将失败
FILE_SHARE_WRITE:其他程序试图使用GENERIC_READ打开文件将失败
FILE_SHARE_READ|FILE_SHARE_WRITE:其他程序打开文件的任何尝试都将成功
2.HANDLE CreateFileMapping(
HANDLE hFile, // 文件句柄
LPSECURITY_ATTRIBUTES lpAttributes, // 安全属性,一般不管
DWORD flProtect, //内存映射文件页的属性
DWORD dwMaximumSizeHigh, // 文件的最大字节数高位
DWORD dwMaximumSizeLow, // 文件最大字节数低位
LPCTSTR lpName // 对象名称,可用于进程间的数据共享
);
flProtect:
PAGE_READONLY:当文件映射对象被映射,可以读取文件的数据
PAGE_READWRITE:当文件映射对象被映射,可以读取文件的数据或者向文件写入数据,设置此属性时,必须以GENERIC_READ|GENERIC_WRITE的方式打开文件
PAGE_WRITECOPY:文件映射对象被映射,可以读取文件的数据或者向文件写入数据,设置此属性时,必须以GENERIC_READ|GENERIC_WRITE的方式打开文件,但与上面的不同是,写入时,会导致页面的私有拷贝的创建
dwMaximumSizeHigh,dwMaximumSizeLow:
设定的内存映射文件的最大的大小,dwMaximumSizeHigh为设定的大小的高32位,dwMaximumSizeHigh为低32位,若文件的大小小于设定的大小,系统会对文件进行扩充(也有不扩充的,也就是不分配存储器,这个在后面讲),如果这两个参数设定0,表示原始大小
3.LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // CreateFileMapping返回的句柄
DWORD dwDesiredAccess, // 访问权限
DWORD dwFileOffsetHigh, // 偏移的高32位
DWORD dwFileOffsetLow, // 偏移的低32位
SIZE_T dwNumberOfBytesToMap // 想要映射到进程的地址空间的字节数量
);
dwDesiredAccess:
4.UnmapViewOfFile 撤销映射
5.关闭内存映射文件的句柄和文件句柄,使用CloseHandle
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string FileName="E:\\sql.txt";
DWORD FileSizeLow,FileSizeHigh;
/*cout<<"请输入想要进行文字转换的文件名称:";
cin>>FileName;*/
HANDLE hFile=CreateFile(FileName.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
cout<<"打开文件失败"<<endl;
return 1;
}
FileSizeLow=GetFileSize(hFile,&FileSizeHigh);//只有超过4G的文件,FileSieHigh才有数值
HANDLE hFileMapping=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,NULL);
if(!hFile)
{
CloseHandle(hFile);
cout<<"创建文件映像失败"<<endl;
return 2;
}
PVOID pFile=MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);
//pFile[FileSizeLow]=0;
int flag=-1;
bool ret=IsTextUnicode(pFile,FileSizeLow,&flag);
if(!ret)
{
_strrev((char*)pFile);
}
else
{
PWSTR wpFile=(PWSTR)pFile;
wpFile++;//Unicode编码方式,前面有个BOM,必须跳过
_wcsrev(wpFile);
}
//IS_TEXT_UNICODE_ASCII16
UnmapViewOfFile(pFile);
CloseHandle(hFileMapping);
CloseHandle(hFile);
system("pause");
return 0;
}