• 文件映射的相关操作流程


               当我们需要对大容量文件进行读写的时候,采用CFile类进行读写的话,操作的效率会不高。而且CFile类本身也不是针对大容量文件设计的,所以我们需要提高读写效率的话,需要进行文件映射。
               文件映射是指将需要读写的内容映射到内存中去,然后由系统对内存进行操作,写入到文件中去,从而大大的提高读写的速度。不过,这个还是得要和你的存储设备本身的读写效率相挂钩!例如在SD卡上的读写效率会低于在Flash上。
               关于文件映射的流程主要是:
               1.创建文件对象
           m_hFile      =  CreateFileForMapping  (  strDataFile GENERIC_READ   GENERIC_WRITE  ,
                  FILE_SHARE_WRITE  ,  NULL ,  OPEN_ALWAYS  , FILE_ATTRIBUTE_NORMAL  |                FILE_FLAG_WRITE_THROUGH  ,0);
               2.创建文件映射内存的对象
    m_hMapFile    =  CreateFileMapping  (  m_hFile ,  NULL   PAGE_READWRITE  ,0, 0x1400000,  NULL  );
       在该部分中,需要我们预先制定我们要生成的文件的大小,例如上面的0x1400000,设定文件最大为20M
               3.获取内存映射文件对象的视图
    m_pData       = ( BYTE  *)  MapViewOfFile  ( m_hMapFile  ,  FILE_MAP_WRITE  ,0,0,0x200000);
    在这里我们需要制定每次映射的内存大小,例如我的文件生成是20M,但是我每次映射都映射2M,等到不够的时候,再重新映射一次即可。例如:
                    if  (  m_dataSize  +  nBufLen  >=0x200000)
                {
                        UnmapViewOfFile  (  m_pData );
                        m_dataSize    = 0;
                        m_pData       = ( BYTE  *)  MapViewOfFile  ( m_hMapFile  ,  FILE_MAP_WRITE  ,0,
                              m_fileSize  ,0x200000);
                }
               完成了文件视图获取和内存块的申请之后,我们开始利用该快内存对文件进行读写操作,将内容写到缓存中去。而且,文件指针需要设置偏移量,而这个偏移量就是用来定位文件的结尾处,保证数据读写的无缝连接!
    memcpy  (  m_pData  +  m_dataSize  , buf  ,  nBufLen );
               在每一次映射的内存块使用完之后需要重新映射的时候,或者需要结束文件的读写的时候,我们需要关闭文件映射。
        UnmapViewOfFile  (  m_pData );
               在关闭文件映射之后,如果我们结束了文件的写入操作的时候,我们需要关闭对象句柄,然后就结束了整个文件映射的流程。
            SetFilePointer  (  m_hFile ,  m_fileSize  ,0, FILE_BEGIN  );
                  SetEndOfFile  ( m_hFile  );
                  UnmapViewOfFile  (  m_pData );
                  CloseHandle  ( m_hMapFile  );
                  CloseHandle  ( m_hFile  );
                上面的code中可以看到,我们需要关闭文件句柄,如果我们最后的文件没有达到20M的话,我们需要将多余的部分截断,所以利用SetFilePointer和SetEndOfFile两个函数就可以根据文件的实际大小而截断多余的空闲内存。
  • 相关阅读:
    jstree 的使用(增 删 改 查)
    关于Random 和 List<int>的Exist的方法使用
    编译器错误消息: CS0016: 未能写入输出文件“c:WindowsMicrosoft.NETFramework64v4.0.30319Temporary ASP.NET Files oot1b124ac2fb984fcApp_global.asax.vbtifrrw.dll”--“拒绝访问。 ”
    SQL Server执行动态SQL正确方式
    C#设计模式——简单说(简单工厂模式)
    c#设计模式——简单说(建造者模式)
    nginx将http请求转发到https
    maven出现:Failed to execute goal on project ...: Could not resolve dependencies for project ...
    动态切换element-ui表格中每行的icon
    axios拦截token过期,返回401的情况
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3180375.html
Copyright © 2020-2023  润新知