zoukankan      html  css  js  c++  java
  • Python:如何将文件映射到内存

    一、说明

     1)什么叫映射?

       ==>就是给一个对象(可以是变量、物理等),起一个唯一的别名,建立一一对应的关系;

     2)文件映射:将磁盘上的文件的位置,与进程逻辑地址空间中一块大小相同的区域之间的一一对应;

     3)映射后得到一个类似数组类型的东西(mmap.mmap()对象),可以通过类似操作数组的方式,达到对文件内容更改的目的;

    二、优点

     1)相对于二进制文件的缺陷

      通常读写文件时,使用read()和write()方法,这两种方法都是以流的形式进行的,也就是一个字节接着一个字节的读写;如果想从某一位置开始读写,使用seek()方法调整文件指针,此方法对二进制文件的操作非常不方便,因为相对于二进制文件,数据写入文件时是以数组的形式,将数据映射到文件内,然后就以访问数组的形式访问文件,而且在对文件进行修改后,能再次通过此数组将数据同步到文件中;

     2)某些嵌入式设备,寄存器被编址到内存地址空间,我们可以映射/dev/mem某范围,取访问这些寄存器

      例如:在树莓派(为学习计算机编程教育设计的一种微型电脑)上,有一个pwm波形的发生器,若想使用此发生器,就要访问树莓派的寄存器;实际上,寄存器就是物理地址的某一特定空间;此时,如果要访问寄存器,需要将 /dev/mem 的某一范围,映射到内存中,用访问内存的方式来访问寄存器;

     3)如果多个进程映射同一个文件,还能实现进程通信的目的

      多个进程把同一个文件映射到各自的内存空间当中,实际上它们看到的是同一个视图,也能实现进程通信的目的;

    三、python中,如何做到文件映射到内存?

     1)方案:使用标准库中mmap模块下的mmap()函数,它需要一个打开的文件描述符作为参数

     2)格式:mmap.mmap(fileno, length[, access[, offset]]])

      #fileno:文件描述符;

       f = open('a.txt', 'w')

       f.fileno(),得到文件a.txt的描述符;

      #length:映射区域的大小,必须以(mmap.PAGSIZE)为单位;

        #页(mmap.PAGSIZE):磁盘的存储单位;

        A、0,表示全部文件;

        B、length = mmap.PAGSIZE * 8:只映射文件的前8页;

      #access:访问权限;如access = mmap.ACCESS_WRITE,表示写的权限;

      #offset:指定映射文件的某一区域,相当于文件指针

        A、指定时必须要以内存的一个页做为单位,进行文件和内存的对齐,也就是说,不能随意跳过一些字节来指定映射区域;

        B、指定的区域必须是页(mmap.PAGESIZE)的整数倍;

        C、offset = mmap.PAGSIZE * 4:表示跳过4页,从第5页开始映射;

     3)例:

    import mmap
    
    f = open('demo.bin', 'rb')
    m = mmap.mmap(f.fileno(), mmap.PAGSIZE * 8, access = mmap.ACCESS_WRITE, offset = mmap.PAGSET * 4)
    #f.fileno():得到demo.bin文件的文件描述符;
    #mmap.PAGSIZE * 8:映射8页;
    #access = mmap.ACCESS_WRITE:以写权限对被映射的文件内容进行操作;
    #offset = mmap.PAGSIZE * 4:从第5页开始对文件进行映射;
    #此处的页,页就是mmap.PAGSIZE是指内存的存储单元;
    #此时文件在磁盘上,并没有被Copy到内存上;
    
    print(type(m))
    #输出:mmap.mmap()
    
    #对单个位置的字节进行更改;
    m[0] = 'x88'
    
    #切片:对一段数据进行更改;长度要和赋值的二进制字符串程度一样;
    m[4:8] = 'x01'*4

     4)其它

      A、不同的平台(也就是系统)上,mmap()函数的使用不同;

      B、文件描述符:是系统调用的open函数,在打开文件时得到的;(os.open())

      C、python中的open()函数也可以得到文件描述符:

  • 相关阅读:
    提升request模块的效率--线程池
    selenium的用法
    SVN 常用命令
    SVN 常见问题及解决方法
    Makefile 详解
    开心一刻(一)
    Vim配置及其他注意事项
    彩虹表
    C++学习之STL(二)String
    C++学习之STL(一)vector
  • 原文地址:https://www.cnblogs.com/volcao/p/8810706.html
Copyright © 2011-2022 走看看