如何使用MMAP函数提高Python中的文件读取性能?
简介..
MMAP 缩写为内存映射,映射到文件时使用操作系统虚拟内存直接访问文件系统上的数据,而不是通过普通的 I/O 函数访问数据。从而提高 I/O 性能,因为它不需要为每次访问进行单独的系统调用或在缓冲区之间复制数据
事实上,内存中的任何内容(例如 SQLlite 数据库)在内存中创建时都比在磁盘上创建时具有更好的性能
内存映射文件可以被视为可变字符串或类似文件的对象,具体取决于您想要执行的操作
MMAP 支持多种方法,例如 close()、flush()、read()、readline()、seek()、tell()、write(),并且可以很好地与切片操作甚至正则表达式配合使用
如何做..
1假设一个文本文件包含以下内容。您只需使用 Google 并搜索示例文本即可获取此文本。 将这些内容复制到 input.txt 文件
Lorem ipsum dolor sat amet,他的第二个原因,duo cu congue prodesset。 Ut Epicuri invenire duo, novumridens eu has, in nature meliore noluisse sea.他有没有做出解释。没有 nam eirmod deterruisset,如果您选择海上口粮巴士,有兴趣的熟食店可以坐一坐。 Purto molestiae cu eum, in per hinc periculis intellegam.
Id 韭菜面暨。这不是真正的 detraxit easy、sit 和 cleta 装饰精华。 Out eam Labores 融合了 menandri,前他的野蛮人继续 eleifend,很好地改变了 argumentum 前。两人在 zril sensibus,我 vim ullum assentior,当 possit 在他身边时。
茶肉临时 posidium scripserit, Eam mundi 镇压痛楚与。 Vim te solea冒犯了民主制度。详细地命名直径,无论有什么异议。真实的传说dignissim ad vis,以前是一项应受谴责的专利,inermis constituam philosophia ne mel。这通常是我们的脑叶。
Nec reque postea Urbanitas ut,意味着不会发生意外。 Ei duo iuvaret numquam。费里再也听不到你的声音了,梅尔和诺路易斯。不,我刚刚拥有 id pro posse apeirian volutpat。我的十四行诗 quaestio 是。
Atqui some Alienum you vim。 Graeco aliquip 发布 pro ut。你们就像过去的改革者,你们是世界上最伟大的人。我的剧本至少是这样,我的初心是,精致的法证法和 vim。而且你说的很平庸,这里是一个eam的总和。
2.我们将使用mmap()函数创建内存映射文件。我们可以通过文件对象的 fileno() 方法或 os.open() 来传递文件名。
注意:用户负责在调用 mmap() 之前打开文件并关闭它。
mmap() 的第二个参数是以字节为单位的大小,指示要映射的文件部分。如果值为 0,则映射整个文件。还有一个附加参数可以使用,ACCESS_READ 用于只读访问,ACCESS_WRITE 用于直写访问,ACCESS_COPY 用于写时复制访问
import mmap
input_text = """Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.
Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam an diam elaboraret, quaeque dissentias an has. Autem legendos dignissim ad vis, sea ex amet petentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.
Nec reque postea urbanitas ut, mea in nulla invidunt ocurreret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.
Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo an eam.
"""
# 创建一个包含一些文本的输入文件
input_file = 'input.txt'
f = open(input_file, "w+")
f.write(input_text)
f.close()
#以读模式打开文件
with open(input_file, 'r') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
print(f"Output \n*** Output first 5 bytes of the {input_file} is {m.read(5)} ")
print(f"*** Output Next 10 bytes of the {input_file} is {m.read(10)} ")
输出
*** Output first 5 bytes of the input.txt is b'Lorem' *** Output Next 10 bytes of the input.txt is b' ipsum dol'
3.我们已读取文件并将其映射到内存,并使用 .read() 读取前 5 个字节。因此,在第一次读取后,文件指针向前移动了 10 个字节。现在,如果您再进行一次读取,假设读取 (10) 个字节,它将为您提供从 6 到 15 个字节。
4.要设置要更新的内存映射文件,请在映射之前将其打开为 'r+'(而不是 'w')。
我将通过一个示例向您展示如何就地修改行的一部分。
import mmap
import Shutil
input_file = 'input.txt'
input_copy = input_file.replace('input','input_copy')
# 复制文件以确保原始文件未被修改。
shutil.copyfile(input_file,input_copy)
# word
word = b'ipsum'
# 修改后的单词
modified_word = word[::-1]
# 打开文件以接收更新
with open(input_copy, 'r+') as f:
with mmap.mmap(f.fileno(), 0) as m:
print(f"output \n *** Line before updates \n {m.readline().rstrip()}")
# 使用 seek 倒退
m.seek(0)
# 查找单词并反转
loc = m.find(word)
m[loc:loc + len(word)] = modified_word
m.flush()
# 使用 seek 倒退
m.seek(0)
print(f" \n *** Line after updates \n {m.readline().rstrip()}")
f.seek(0)
print(f" \n *** Final file \n {f.readline().rstrip()}")
输出
*** Line before updates b'Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.' *** Line after updates b'Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.' *** Final file Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
5.内存和文件中第一行中间的单词"ipsum"被替换。
6.如果出于某种原因,您想查看内存中的更改,而不想更新磁盘上的文件,请使用 ACCESS_COPY。
import mmap
import Shututil
input_file = 'input.txt'
input_copy = input_file.replace('input','input_copy')
# 复制文件,以确保原始文件未被修改。
Shututil.copyfile(input_file,input_copy)
# word
word = b'ipsum'
# 修改后的单词
modified_word = word[::-1]
# 打开文件以接收更新
with open(input_copy, 'r+') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_COPY) as m:
print(f"output \n *** Line before updates \n {m.readline().rstrip()}")
# 使用 seek 倒退
m.seek(0)
# 查找单词并反转
loc = m.find(word)
m[loc:loc + len(word)] = modified_word
m.flush()
# 使用 seek 倒退
m.seek(0)
print(f" \n *** Line after updates \n {m.readline().rstrip()}")
f.seek(0)
print(f" \n *** Final file \n {f.readline().rstrip()}")
输出
*** Line before updates b'Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.' *** Line after updates b'Lorem muspi dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.' *** Final file Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
7.观察,输入和输出中的内容都没有改变,而变化只应用于内存中。
相关文章
有用资源
python 参考教程 - 该教程包含有关 python 的更多信息:https://www.cainiaomax.com/python/

