Python3 mmap内存映射文件示例解析
作者:爱编程的小灰灰 发布时间:2021-07-14 15:05:50
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字节。
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”将被替换。
使用访问设置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句柄,因为这两个对象的内部状态会单独维护。
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语句会找到匹配的句子,并用空格代替换行符,使各个结果都打印在同一行上。
来源:https://www.cnblogs.com/liuhui0308/p/12492403.html


猜你喜欢
- int 数字python 有3种数字类型int: 整数类型float: 浮点类型complex: 复数类型int类型#Int或整数是完整的数
- 最近接触了很多数据库的东西,本来是一直接触的是sql server,不过由于项目需要就开始对mysql进行了连接。下面就让我这个菜鸟浅谈下经
- 当有两个表,例如一个学生表,一个班级表,是多对一的关系。方法1:c = models.Class.object.get(pk=1)#查询到I
- 5. 其他杂项 5.1 生成图像PHP可以操作处理图像。如果你已经安装了GD库,你甚至可以利用PHP生成图像。
- 一、说明之前写了一篇“Python执行系统命令教程”讲了如何执行系统命令。除了执行系统命令外,我们有时还需要动态地执行一些python代码,
- Filed under 数据库技术Leave a commentSQL Server命令行导数据两种方式bcp和sqlcmd先说一下bcp:
- python进行矩阵运算的方法:1、矩阵相乘>>>a1=mat([1,2]); >>>a2
- 关于cookie和session估计很多程序员面试的时候都会被问到,这两个概念在写web以及爬虫中都会涉及,并且两者可能很多人直接回答也不好
- RegExp对象的语义和使用:检查字符串匹配获取字符串中的部分内容在原字符串的基础上构建一个新的字符串(包括添加、删除和修改)构建一个Reg
- Hello,Everyone!Python是个好东西!好吧,以黎某人这寒碜的赞美之词,实在上不了台面,望见谅。那我们直接来上干货吧。第一步:
- 本文实例为大家分享了python批量处理图片的具体代码,供大家参考,具体内容如下公司的一个项目要求把所有4096x4096的图片全部转化成2
- 1.新建site-packages目录,进入到site-packages目录下;2.在site-packages目录下执行pip freez
- 什么是迭代(iteration)呢?给定一个list或者tuple,通过for循环来遍历这个list或者tuple、这种遍历就是迭代(ite
- 一、问答平台这个「生活常识解答」机器人采用的是:阿里达摩院发布的语言模型PLUG(最近刚发布的,目前是测试阶段),地址链接如下:https:
- 可以使用 Application 对象在给定的应用程序的所有用户之间共享信息。基于 ASP 的应用程序同所有的 .asp 文件一样在一个虚拟
- 在一个项目中,制作呃echart图表的时候,遇到一个需求,需要从后端接口获取数据----售票员的姓名和业绩所以需要在订单表中,获取不同售票员
- 本文实例为大家分享了vue组件watch属性的具体代码,供大家参考,具体内容如下<!doctype html><html&
- linux默认是安装了python,默认是安装python2.6.6,可能安装的版本是不能符合我们需要的python要求的。我们需要重新安装
- 题目描述将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。LeetCode原题地址:https:/
- 本文实例讲述了Python实现将一个正整数分解质因数的方法。分享给大家供大家参考,具体如下:遇到一个python编程联系题目:将一个正整数分