• 内存映射文件


    内存映射文件
    内存映射文件的概念内存映射文件提供了一组独立的函数,使应用程序能够通过内存指针像访问内存一样访问磁盘上的文件。通过内存映射文件函数可以将磁盘上的文件全部或者部分映射到进程的虚拟地址空间的某个位置。一旦完成映射,对磁盘文件的访问就可以像访问内存文件一样便捷。
    使用内存映射文件的好处
    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;
  • 相关阅读:
    linux查看java jdk安装路径和设置环境变量
    linq where in 排序
    Console程序后台运行
    winform中文本框,软键盘跟随
    winform 应用log4net做日志记录到mysql
    c# 单实例运行
    Sql Server数据库监听 c#代码
    winform程序开机自动启动
    c# 连接mysql配置config,不用装net connector
    winform 不规则窗体无锯齿demo
  • 原文地址:https://www.cnblogs.com/jxgxy/p/2081333.html
Copyright © 2020-2023  润新知