• 内存映射


    内存映射文件,是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个进程的函数 (CreateFileMapping)。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。


    内存映射文件
     
    内存映射文件的概念内存映射文件提供了一组独立的函数,使应用程序能够通过内存指针像访问内存一样访问磁盘上的文件。通过内存映射文件函数可以将磁盘上的文件全部或者部分映射到进程的虚拟地址空间的某个位置。一旦完成映射,对磁盘文件的访问就可以像访问内存文件一样便捷。
     
    使用内存映射文件的好处
    a系统使用内存映射文件,以便加载和执行.exeDLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。
    b可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作,并且可以不必对文件内容进行缓存。
    c可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据。注:使用内存映射文件数据传输是通过4k大小的数据页面实现的。
     
    内存映射文件的实现原理
    先来看看windows的页式虚拟存储管理,在windows中,每一个页面在一个时刻都是处于一下三种情况之一:空闲的,挂起的还有已经提交的。
    当某个页面不需要的时候windows可以将其从内存中调换出来,需要的时候页面可以重新再次从物理存储器读入内存。内存映射文件的实现原理与此相似,内存映射文件也保留了一个地址空间的区域,并根据需要将物理存储器提交到该区域。
    区别是:内存映射文件存取一个磁盘文件时,它提交的物理存储器就是来自该文件~!

     
    内存映射文件函数包括:  
    CreatFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFileFlushViewOfFile.
     
     
    使用内存映射文件的步骤分两步
    使用CreatFileMapping创建一个内存映射文件对象
    Invoke  CreatFileMapping,hFile,lpFilemappingAttributes, flProtect,dwMaximumSizeHigh,\
    dwMaximumSizeLow ,lpName
    .if eax
    mov hFileMap,eax
    .endif
    这个函数确定了映射文件的用途:
    在磁盘文件建立内存映射文件还是在内存页面上建立进程间共享的映射。
     
    通过设置第一个参数hFile的值可以实现上面的功能。如果hFile句柄是属于一个已经打开的文件,那么映射文件就在这个文件上建立。如果想建立存在于内存文件中内存映射文件供不同进程共享,则将hFile指定为-1
    lpFilemappingAttributes
    :内存映射文件对象是否可以被继承。不被继承使用NULL
    flProtect
     内存映射文件的保护方式,注意要在用CreatFile函数打开文件获得hFile句柄的时候必须指定相应的标志flProtect
    dwMaximumSizeHigh/dwMaximumSizeLow::指定64位内存映射文件的长度。将这两参数设置为零,系统会自动将内存映射文件的大小调整到磁盘文件的大小。
    lpName
    内存映射文件的名字。用于进程共享的时候映射文件必须起名字。

    使用OpenFileMapping 打开已经建立的用于进程共享的内存映射文件。 
          Invoke  OpenFileMapping,dwDesiredAccess,bInheritHandle, lpName
          .if   eax
                   Mov hFileMap, eax
          .endif
    dwDesiredAccess
    :指定保护类型。
    lpName            
    创建对象时使用的名字。
    bInheritHandle 
     继承文件的句柄。

    2 创建内存映射文件的一个视图。相当于给内存映射文件分配线形地址空间,并将线形地址与文件的内容相关联。这样应用程序可以通过存取线形地址来存取文件。
    Invoke  MapViewOfFile,hFileMap,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,\
                dwNumberOfBytesToMap
    .if eax
            Mov ipMemory,eax
    .endif
    不多说了这个函数的参数很简单。
    取消映射文件:invoke UnmapViewOfFile,lpMemory
    关闭映射文件:invoke CloseHandle,hFileMap
     
     
    将对文件的修改立即写到磁盘上是调用这个函数实现的 Invoke FlushViewOfFile, lpMemory, dwFileSize 
     
     
    现在总结一下
    使用内存映射文件进行读写文件的步骤:
    1
    调用 CreatFile 打开想要映射的文件,获得hFile
    2
    调用 CreatFileMapping 函数生成一个建立在CreatFile函数创建的文件对象基础上的内存映射对象,得到hFileMap
    3
    调用 MapViewOfFile 函数把整个文件的一个区域或者整个区域映射到内存中,得到指向映射到内存的第一个字节的指针 lpMemory
    4
    用该指针来读写文件
    5
    调用 UnmapViewOfFile 来解除文件映射,传入参数为 lpMemory
    6
    调用 CloseHandle 来关闭内存映射文件,传入参数为 hFileMap
    7
    调用 CloseHandle 来关闭文件,传入函数为 hFile

  • 相关阅读:
    实现Path2.0中绚丽的的旋转菜单
    ColorMatrixColorFilter颜色过滤(离线用户的灰色头像处理)
    网上发现的一个android UI包
    圆角背景的ListView
    自定义Gallery 滑动中图片自动突出显示
    python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)
    Linux(deepin) 系统: 解决 matplotlib 中文乱码问题
    python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)
    API接口防止参数篡改和重放攻击
    API接口防止参数篡改和重放攻击
  • 原文地址:https://www.cnblogs.com/lexus/p/1845179.html
Copyright © 2020-2023  润新知