美文网首页
4.13 使用MappingFile提高文件读写效率

4.13 使用MappingFile提高文件读写效率

作者: f675b1a02698 | 来源:发表于2017-09-14 16:16 被阅读0次

    说明

    图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;

    }

    相关文章

      网友评论

          本文标题:4.13 使用MappingFile提高文件读写效率

          本文链接:https://www.haomeiwen.com/subject/tygqsxtx.html