说明
图1:执行正常
图2:0x20000处的32字节已经给修改
图3:0x28804处的值读取正确
效果
源码
#include
#include
#define BUFFSIZE 1024//内存大小
#define FILE_MAP_START 0x28804//文件映射的起始位置
LPTSTR lpcTheFile = TEXT("misaka.dat");//文件名
int main(int argc, PCHAR argv[]){
HANDLE hMapFile;//文件内存映射句柄
HANDLE hFile;//文件句柄
DWORD dBytesWritten;//写入的字节数
DWORD dwFileSize;//文件大小
DWORD dwFileMapSize;//文件映射的大小
DWORD dwMapViewSize;//视图大小
DWORD dwFileMapStart;//文件映射视图的起始位置
DWORD dwSysGran;//系统内存分配粒度
SYSTEM_INFO SysInfo;//系统信息
LPVOID lpMapAddress;//内存映射区域的起始位置
PCHAR pData;//数据
INT i;//循环变量
INT iData;
INT iViewDelta;
BYTE cMapBuffer[32];//存储从映射中计出的数据
//创建一个文件
hFile = CreateFile(lpcTheFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
printf("创建文件失败: %s\n", GetLastError());
return 1;
}
//依次写入整数,一共写入65535个
//在32位平台下,大小为65535*4字节
for (i = 0; i< 65535; i++){
WriteFile(hFile, &i, sizeof(i), &dBytesWritten, NULL);
}
//查看写入完成后的文件大小
dwFileSize = GetFileSize(hFile, NULL);
printf("文件大小: %d\n", dwFileSize);
//获得系统信息,内存分配粒度,目的是为了映射的数据与系统内存分配粒度对齐,提高内存访问效率
GetSystemInfo(&SysInfo);
dwSysGran = SysInfo.dwAllocationGranularity;
//计算mapping的起始位置
dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran;
//计算mapping view的大小
dwMapViewSize = (FILE_MAP_START % dwSysGran) + BUFFSIZE;
//计算mapping的大小
dwFileMapSize = FILE_MAP_START + BUFFSIZE;
//计算需要读取的数据的偏移
iViewDelta = FILE_MAP_START - dwFileMapStart;
//创建file mapping
hMapFile = CreateFileMapping(
hFile,//需要映射的文件的句柄
NULL,//安全选项:默认
PAGE_READWRITE,//可读可写
0,//mapping对象的大小 high
dwFileMapSize,//mapping对象的大小 low
NULL//mapping对象的名字
);
if (hMapFile == NULL){
printf("创建文件映射对象失败: %d\n", GetLastError());
return 1;
}
//映射视图
lpMapAddress = MapViewOfFile(
hMapFile,//mapping对象的句柄
FILE_MAP_ALL_ACCESS,//可读可写
0,//映射文件偏移 high
dwFileMapStart,//映射文件偏移 low
dwMapViewSize//映射到视图的数据大小
);
if (lpMapAddress == NULL){
printf("映射文件视图失败: %d\n", GetLastError());
return 1;
}
printf("文件映射视图相对于文件的起始偏移位置: 0x%x\n", dwFileMapStart);
printf("文件映射视图的大小: 0x%x\n", dwMapViewSize);
printf("文件映射对象的大小: 0x%x\n", dwFileMapSize);
printf("从相对于映射视图 0x%x 字节的位置读取数据", iViewDelta);
//将指向数据的指针偏移,到达我们关系的地方
pData = (PCHAR)lpMapAddress + iViewDelta;
//读取数据,赋值给变量
iData = *(PINT)pData;
//显示读取的数据
printf("为: 0x%.8x\n", iData);
//从mapping中赋值数据,32字节并打印
CopyMemory(cMapBuffer, lpMapAddress, 32);
printf("lpMapAddress起始的字节是: ");
for (i = 0; i< 32; i++){
printf("0x%.2x ", cMapBuffer[i]);
}
//将mapping的前32字节用0xff填充
FillMemory(lpMapAddress, 32, (BYTE)0xff);
//将映射的数据写回到硬盘
FlushViewOfFile(lpMapAddress, dwMapViewSize);
printf("\n已将lpMapAddress开始的字节使用0xff填充\n");
//关闭mapping对象
if (!CloseHandle(hMapFile)){
printf("关闭映射对象失败: %d\n", GetLastError());
}
//关闭文件
if (!CloseHandle(hFile)){
printf("关闭文件对象失败: %d\n", GetLastError());
}
getchar();
return 0;
}
网友评论