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
猜你喜欢
- class和id的命名,如果合理,可以使得文档具有清晰的结构我们现在解决办法就是使用现有的元素,通过给他们id或class而得到额外的信息。
- 巨坑,切忌不要轻易删除Linux系统自带版本的Python1.卸载python(防止未卸载干净)rpm -qa|grep python|xa
- 1,filesize()函数返回错误的值。 使用curl将某个页面下载到本地时,需要将下载到的临时文件tmpHtml.txt的内容读取到一个
- 以下代码比较简单,对python实现ftp上传文件相关知识感兴趣的朋友可以参考下#encoding=utf8from ftplib impo
- 下面就是我们的authenticate.asp页面,在这里,将用户的信息收集起来,连同最初的URL一起传到一个识别用户身份的页面中。我们可用
- 背景简介别踩白板这个游戏相信大家都玩过,这个是基于HTML5打造的简单小游戏,在PC端和移动端都能够运行,适应多种平台,今天我们使用原生JS
- 代码如下:ALTER proc [dbo].[sp_common_paypal_AddInfo] ( @paypalsql va
- 当然首先得去下载ASPupload 程序,安装后使用!官方网站下载:http://www.aspupload.com/使用ASP实现文件上载
- import Exception# except 在捕获错误异常的时候 是要根据具体的错误类型来捕获的# 用一个块 可以捕获多个不同类型的异
- 一、下载安装包http://www.php.net/downloads.php获取下载地址wgethttp://hk1.php.net/di
- 前言昨天因为小程序功能要获取小程序程序码,看了微信文档爬了好多坑。(留一下记录以防后面被坑)操作因为我获取到了微信那里的图片的图片流一直不知
- 我们首先来看下实例代码:function sig_handler($sig){ print("handled sig:
- 1. 非 matlab v7.3 files 读写import scipy.io as sioimport numpy# matFile 读
- 这篇论坛文章(赛迪网技术社区)主要介绍了一种简单的MySQL数据库安装方法,详细内容请大家参考下文:虽然安装MySQL数据库的文章很多,但是
- 跑代码时,在命令行给python程序传入bool参数,但无法传入False,无论传入True还是False,程序里面都是True。下面是代码
- 1:php地址 http://127.0.0.6/?c=json2:java 输出的结果是[{"i
- 数组:复制传递(不要按照c/c++的方式去理解,c/c++中数组是引用传递),定长切片:引用传递,底层实现是3个字段 array(数组) +
- 简介:这里是利用了selenium+图片识别验证,来实现12306的模拟登录,中间也参考了好几个项目,实现了这个小demo,中间也遇到了很多
- 如何在ADO服务器端利用好缓存技术?请看下面示例,这是一个用来显示图书分类的例子程序:displayBooks.asp< %
- 两段使用键盘的上下键进行选择的代码:<Script Language="JScript"> &