Python3 mmap内存映射文件示例解析


Posted in Python onMarch 23, 2020

1. mmap内存映射文件

建立一个文件的内存映射将使用操作系统虚拟内存来直接访问文件系统上的数据,而不是使用常规的I/O函数访问数据。内存映射通常可以提供I/O性能,因为使用内存映射是,不需要对每个访问都建立一个单独的系统调用,也不需要在缓冲区之间复制数据;实际上,内核和用户应用都能直接访问内存。

内存映射文件可以看作是可修改的字符串或类似文件的对象,这取决于具体的需要。映射文件支持一般的文件API方法,如close()、flush()、read()、readline()、seek()、tell()和write()。它还支持字符串API,提供分片等特性以及类似find()的方法。

下面的所有示例都会使用文本文件lorem.txt,其中包含一些Lorem Ipsum。为便于参考,下面的代码清单给出这个文件的文本。

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec egestas, enim et consectetuer ullamcorper, lectus ligula rutrum leo,
a elementum elit tortor eu quam. Duis tincidunt nisi ut ante. Nulla
facilisi. Sed tristique eros eu libero. Pellentesque vel
arcu. Vivamus purus orci, iaculis ac, suscipit sit amet, pulvinar eu,
lacus. Praesent placerat tortor sed nisl. Nunc blandit diam egestas
dui. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Aliquam viverra fringilla
leo. Nulla feugiat augue eleifend nulla. Vivamus mauris. Vivamus sed
mauris in nibh placerat egestas. Suspendisse potenti. Mauris
massa. Ut eget velit auctor tortor blandit sollicitudin. Suspendisse
imperdiet justo.

1.1 读文件

使用mmap()函数可以创建一个内存映射文件。第一个参数是文件描述符,可能来自file对象的fileno()方法,也可能来自os.open()。调用者在调用mmap()之前负责打开文件,不再需要文件时要负责将其关闭。

mmap()的第二个参数是要映射的文件部分的大小(以字节为单位)。如果这个值为0,则映射整个文件。如果这个大小大于文件的当前大小,则会扩展该文件。

这两个平台都支持一个可选的关键字参数access。使用ACCESS_READ表示只读访问;ACCESS_WRITE表示“写通过”(write-through),即对内存的赋值直接写入文件;ACCESS_COPY表示“写时复制”(copy-on-write),对内存的赋值不会写至文件。

import mmap
with open('lorem.txt', 'r') as f:
  with mmap.mmap(f.fileno(), 0,
          access=mmap.ACCESS_READ) as m:
    print('First 10 bytes via read :', m.read(10))
    print('First 10 bytes via slice:', m[:10])
    print('2nd  10 bytes via read :', m.read(10))

文件指针会跟踪通过一个分片操作访问的最后一个字节。在这个例子中,第一次读之后,指针向前移动10个字节。然后由分片操作将指针重置回文件的起点位置,并由分片使指针再次向前移动10个字节。分片操作之后,再调用read()会给出文件的11~20字节。

Python3 mmap内存映射文件示例解析

1.2 写文件

要建立内存映射文件来接收更新,映射之前首先要使用模式'r+'(而不是'w')打开文件以便完成追加。然后可以使用任何改变数据的API方法(例如write()或赋值到一个分片等)。

下面的例子使用了默认访问模式ACCESS_WRITE,并赋值到一个分片,以原地修改某一行的一部分。

import mmap
import shutil
# Copy the example file
shutil.copyfile('lorem.txt', 'lorem_copy.txt')
word = b'consectetuer'
reversed = word[::-1]
print('Looking for  :', word)
print('Replacing with :', reversed)
with open('lorem_copy.txt', 'r+') as f:
  with mmap.mmap(f.fileno(), 0) as m:
    print('Before:\n{}'.format(m.readline().rstrip()))
    m.seek(0) # rewind
    loc = m.find(word)
    m[loc:loc + len(word)] = reversed
    m.flush()
    m.seek(0) # rewind
    print('After :\n{}'.format(m.readline().rstrip()))
    f.seek(0) # rewind
    print('File :\n{}'.format(f.readline().rstrip()))

内存的文件中第一行中间的单词“consectetuer”将被替换。

Python3 mmap内存映射文件示例解析

使用访问设置ACCESS_COPY时不会把修改写入磁盘上的文件。

import mmap
import shutil
# Copy the example file
shutil.copyfile('lorem.txt', 'lorem_copy.txt')
word = b'consectetuer'
reversed = word[::-1]
with open('lorem_copy.txt', 'r+') as f:
  with mmap.mmap(f.fileno(), 0,
          access=mmap.ACCESS_COPY) as m:
    print('Memory Before:\n{}'.format(
      m.readline().rstrip()))
    print('File Before :\n{}\n'.format(
      f.readline().rstrip()))
    m.seek(0) # rewind
    loc = m.find(word)
    m[loc:loc + len(word)] = reversed
    m.seek(0) # rewind
    print('Memory After :\n{}'.format(
      m.readline().rstrip()))
    f.seek(0)
    print('File After  :\n{}'.format(
      f.readline().rstrip()))

在这个例子中,必须单独的回转文件句柄和mmap句柄,因为这两个对象的内部状态会单独维护。

Python3 mmap内存映射文件示例解析

1.3 正则表达式

由于内存映射文件就类似于一个字符串,因此也常与其他处理字符串的模块一起使用,如正则表达式。下面的例子会找出所有包含“nulla”的句子。

import mmap
import re
pattern = re.compile(rb'(\.\W+)?([^.]?nulla[^.]*?\.)',
           re.DOTALL | re.IGNORECASE | re.MULTILINE)
with open('lorem.txt', 'r') as f:
  with mmap.mmap(f.fileno(), 0,
          access=mmap.ACCESS_READ) as m:
    for match in pattern.findall(m):
      print(match[1].replace(b'\n', b' '))

由于这个模式包含两个组,所以findall()的返回值是一个元组序列。print语句会找到匹配的句子,并用空格代替换行符,使各个结果都打印在同一行上。

Python3 mmap内存映射文件示例解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python脚本实现DNSPod DNS动态解析域名
Feb 14 Python
Python判断字符串与大小写转换
Jun 08 Python
编写Python爬虫抓取暴走漫画上gif图片的实例分享
Apr 20 Python
Pycharm学习教程(3) 代码运行调试
May 03 Python
使用anaconda的pip安装第三方python包的操作步骤
Jun 11 Python
python 列表,数组和矩阵sum的用法及区别介绍
Jun 28 Python
python中的常量和变量代码详解
Jul 25 Python
搭建python django虚拟环境完整步骤详解
Jul 08 Python
pandas通过字典生成dataframe的方法步骤
Jul 23 Python
Python2和3字符编码的区别知识点整理
Aug 08 Python
django 扩展user用户字段inlines方式
Mar 30 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
Jun 02 Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 #Python
python实现横向拼接图片
Mar 23 #Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 #Python
python实现拼接图片
Mar 23 #Python
python使用PIL剪切和拼接图片
Mar 23 #Python
python异常处理、自定义异常、断言原理与用法分析
Mar 23 #Python
python实现单张图像拼接与批量图片拼接
Mar 23 #Python
You might like
php简单实现文件或图片强制下载的方法
2016/12/06 PHP
php实现的中秋博饼游戏之掷骰子并输出结果功能详解
2017/11/06 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
firefox浏览器不支持innerText的解决方法
2013/08/07 Javascript
JS中操作JSON总结
2020/12/06 Javascript
实用框架(iframe)操作代码
2014/10/23 Javascript
Bootstrap每天必学之模态框(Modal)插件
2016/04/26 Javascript
基于jquery插件实现拖拽删除图片功能
2020/08/27 Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
2016/10/28 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
2016/11/25 Javascript
jQuery实现可拖拽3D万花筒旋转特效
2017/01/03 Javascript
你不知道的 javascript【推荐】
2017/01/08 Javascript
激动人心的 Angular HttpClient的源码解析
2017/07/10 Javascript
浅谈Vue CLI 3结合Lerna进行UI框架设计
2019/04/14 Javascript
微信小程序如何使用云开发
2019/05/17 Javascript
使用Vue CLI创建typescript项目的方法
2019/08/09 Javascript
基于better-scroll 实现歌词联动功能的代码
2020/05/07 Javascript
[42:25]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第三场
2018/04/06 DOTA
[37:02]OG vs INfamous 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python中对列表排序实例
2015/01/04 Python
Python smallseg分词用法实例分析
2015/05/28 Python
python技能之数据导出excel的实例代码
2017/08/11 Python
matplotlib绘图实例演示标记路径
2018/01/23 Python
python安装模块如何通过setup.py安装(超简单)
2018/05/05 Python
python sort、sort_index方法代码实例
2019/03/28 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
python中通过pip安装库文件时出现“EnvironmentError: [WinError 5] 拒绝访问”的问题及解决方案
2020/08/11 Python
你不知道的葡萄干处理法、橙蜜处理法、二氧化碳酵母法
2021/03/17 冲泡冲煮
教师自我剖析材料(群众路线)
2014/09/29 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
MySQL命令无法输入中文问题的解决方式
2021/08/30 MySQL