zoukankan      html  css  js  c++  java
  • 内存映射文件

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

    内存映射文件函数包括:  
    CreatFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFileFlushViewOfFile.
    使用内存映射文件的步骤分两步
    1
    使用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

    例子:

    procedure TForm4.Button1Click(Sender: TObject);
    var
      FileName: 
    string;
      FileHandle: THandle;
      FileMapHandle: THandle;
      Address: PChar;
      n: Integer;
    begin
      FileName :
    = ExtractFilePath(Application.ExeName) + 'gshop.data';
      FileHandle :
    = FileOpen(FileName, fmOpenReadWrite);
      
    if FileHandle > 0 then
      
    begin
        FileMapHandle :
    = CreateFileMapping(FileHandle, nil, PAGE_READWRITE, 000);
        
    if FileMapHandle > 0 then
        
    begin
          Address:
    = MapViewOfFile(FileMapHandle, FILE_MAP_ALL_ACCESS, 000);
          
    if Address <> nil then
          
    begin
            n :
    = 10;
            Move(n, PByte(Address 
    + 7)^, 1); //
            ShowMessage(IntToStr(PByte(Address 
    + 7)^));

            n :
    = 0;
            Move(PByte(Address 
    + 7)^, n, 1); //
            ShowMessage(IntToStr(n));

          
    end;
          UnmapViewOfFile(Address);
        
    end;
        CloseHandle(FileMapHandle);
      
    end;
      CloseHandle(FileHandle);
    end;
  • 相关阅读:
    ubuntu 14.04+apache 反向代理设置
    ubuntu 14.04 使用apt-get出现如下问题解决办法
    ubuntu 出现 Unable to locate package update 解决办法
    在ubuntu 12.04 apache 限制IP访问的方法
    (原创)在ubuntu 14.04 中安装Apache2+modsecurity+awstats (新手教程)
    windows 10 的安装说明
    前端三大主流框架中文文档
    关于移动端影像配置了https之后拍出来的照片在android手机无法显示的问题
    ES5常用api
    promise循环调用异步函数(以图片上传为例)
  • 原文地址:https://www.cnblogs.com/jxgxy/p/2081333.html
Copyright © 2011-2022 走看看