mmap:内存映射文件

心不动则不痛 提交于 2019-12-04 17:57:42

介绍

建立一个文件的内存映射将使用操作系统虚拟内存来直接访问文件系统上的数据,而不是使用常规的I/O函数访问数据。 内存映射通常可以提高I/O性能,因为使用内存映射时,不需要对每一个访问都建立一个单独的系统调用,也不需要你在缓冲区之间复制数据。实际上内核和用户应用都能直接访问内存。 内存映射文件可以看做是可修改的字符串或类似文件的对象,这取决于具体的需要。 映射文件支持一般文件的API方法,如close、flush、read、readline、seek、tell、write。他还支持字符串的API,提供切片等特性以及类似find的方法 。

读文件

import mmap

'''
使用mmap函数可以创建一个内存映射文件。第一个参数是文件描述符,可能来自file对象的fileno方法,也可能来自os.open。
调用者在调用mmap方法之前负责打开文件,不再需要文件时要负责将其关闭。
mmap函数的第二个参数是要映射的文件部分的大小(以字节为单位)。如果这个值为0,则映射整个文件,如果这个大小大于文件的当前大小,则会扩展该文件。
注意:Windows不支持长度为0的映射
'''

'''
这两个平台都支持一个可选的参数access。使用ACCESS_READ表示只读访问;ACCESS_WRITE表示“写通过(write-through)”,即对内存的赋值直接写入文件;
ACCESS_COPY表示“写时赋值(copy-on-write)”, 堆内存的赋值不会写入文件
'''
with open(r"C:\python37\Lib\asyncio\sslproto.py", "r", encoding="utf-8") as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
        print("first 10 bytes via read:", m.read(10))  # first 10 bytes via read: b'import col'
        print("first 10 bytes via slice:", m[: 10])  # first 10 bytes via slice: b'import col'
        print("2nd   10 bytes via read:", m.read(10))  # 2nd   10 bytes via read: b'lections\r\n'
'''
可以看到既可以通过切片访问,也可以通过read访问。通过read访问,会使得指针移动,但是切片无论何时都是从头读取,并且对文件指针的移动没有任何影响。
在这个例子中:第一次读取,指针向前移动10个字节,然后由切片操作,对文件指针无影响
切片操作之后,再调用read会给出文件的11~20个字节。
'''

写文件

import mmap

'''
要建立内存映射文件来接收更新,映射之前首先要使用模式r+(而不是w,w的话直接清空了)打开文件以便完成追加。然后可以使用任何可以改变数据的API方法。
'''

with open("1.txt", "r+", encoding="utf-8") as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_WRITE) as m:
        print(m.read())  # b'**pandas** is a Python package'
        m.seek(0)
        loc = m.find(b"Python")
        m[loc: loc + len("Python")] = b"pYTHON"
        print(m.read())  # b'**pandas** is a pYTHON package'
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!