楔子

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

实际上内核和用户应用都能直接访问内存。 内存映射文件可以看做是可修改的字符串或类似文件的对象,这取决于具体的需要。 映射文件支持一般文件的API方法,如close、flush、read、readline、seek、tell、write。而且还支持字符串的API,提供切片等特性以及类似find的方法 。

文件如下:

读文件

使用mmap函数可以创建一个内存映射文件。第一个参数是文件描述符,可以来自file对象的fileno方法,也可以来自os.open。

调用者在调用mmap方法之前负责打开文件,不再需要文件时要负责将其关闭。

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

import mmap

with open("1.txt", "r", encoding="utf-8") as f:
'''
有一个可选的参数access。使用ACCESS_READ表示只读访问;
当然还有写,但是说实话,写的话不常用
'''
# 我们这里是读文件所以是mmap.ACCESS_READ
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
print(m) # <mmap.mmap object at 0x0000025FDA97A150>

直接打印的话,显示的是一个mmap.mmap对象,这个对象内部支持普通文件的一些api。

read方法:

import mmap

with open("1.txt", "r", encoding="utf-8") as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
# 调用m.read()得到文件内容,以字节的形式
print(m.read().decode("utf-8"))
"""
你怎么这么熟练啊!
晨意微寒秋渐深,侧伴无事俏佳人
为了我,你就永远当个废物吧;为了能让我好好努力,就一生,都成为我的负担吧。
我喜欢这个世界上最糟糕的你,最喜欢了。
第一次,有了喜欢的人,还得到了一生的挚友,两份喜悦相互重叠,这双重的喜悦又带来了更多更多的喜悦
是我,是我先,明明都是我先来的,接吻也好,拥抱也好,还是喜欢上那家伙也好
"""
# 由于读取完毕,所以再次读取得到的是空字节
print(m.read()) # b''

readline方法:

import mmap

with open("1.txt", "r", encoding="utf-8") as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
# readline,按照行读取
for _ in range(3):
print(m.readline().decode("utf-8"))
"""
你怎么这么熟练啊! 晨意微寒秋渐深,侧伴无事俏佳人 为了我,你就永远当个废物吧;为了能让我好好努力,就一生,都成为我的负担吧。 """
# 由于有换行符,所以会有空行

size方法:

import mmap

with open("1.txt", "r", encoding="utf-8") as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
# 这个是查看文件的字节数,注意:是使用utf-8转换成字节所对应的字节数
print(m.size()) # 499

当然也支持tell方法,表示当前文件指针所在的位置;以及seek,移动的文件的某个位置。

mmap.mmap对象最大的特点是支持像字符串一样访问数据,我们来看一下:

import mmap

with open("1.txt", "r", encoding="utf-8") as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
print(m.read(9).decode("utf-8")) # 你怎么
print(m[0: 9].decode("utf-8")) # 你怎么
print(m.read(9).decode("utf-8")) # 这么熟

可以看到可以通过切片访问指定位置的内容,另外通过read访问也是可以的。通过read访问,会使得指针移动,但是切片无论何时都是从头读取,并且对文件指针的移动没有任何影响。

但是由于不同的字符占据不同的编码,比如汉字一个字符占三个字节,那么我们截取的时候要是3的整倍数。但如果是中英文混合的话,就比较尴尬了,所以这种方式比较适合纯ascii文本。

此外mmap.mmap对象还支持通过find和rfind定位指定字符所在的位置。

mmap:内存映射文件的更多相关文章

  1. mmap - 内存映射文件 - 减少一次内核空间内数据向用户空间数据拷贝的操作

    关于mmap 网上有很多有用的文章,我这里主要记录,日常使用到mmap时的理解: https://www.cnblogs.com/huxiao-tee/p/4660352.html 测试代码: htt ...

  2. linux mmap 内存映射【转】

    转自:http://blog.csdn.net/xyyangkun/article/details/7830313 [-] mmap vs readwritelseek mmap vs malloc ...

  3. linux mmap 内存映射

    mmap() vs read()/write()/lseek() 通过strace统计系统调用的时候,经常可以看到mmap()与mmap2().系统调用mmap()可以将某文件映射至内存(进程空间), ...

  4. python标准库基础之mmap:内存映射文件

    #作用:建立内存映射文件而不是直接读取内容文本信息内容:如下(名称是text.txt) Lorem ipsum dolor sit amet, consectetuer adipiscing elit ...

  5. Python之mmap内存映射模块(大文本处理)说明

    背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过 ...

  6. 【转】Python之mmap内存映射模块(大文本处理)说明

    [转]Python之mmap内存映射模块(大文本处理)说明 背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力 ...

  7. NET 4 中 内存映射文件

    原文链接 : http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net- ...

  8. 内存映射文件(Memory-Mapped File)

    Java Memory-Mapped File所使用的内存分配在物理内存而不是JVM堆内存,且分配在OS内核. 1: 内存映射文件及其应用 - 实现一个简单的消息队列 / 计算机程序的思维逻辑 在一般 ...

  9. JAVA I/O(三)内存映射文件

    <Java编程思想>中对内存映射文件有详细的介绍,此处仅做简单记录和总结.内存映射文件允许创建和修改因为太大而不能放入内存的文件. 1. 内存映射文件简单实例 import java.io ...

随机推荐

  1. 查看mycat日志

    查看日志: tail -f /usr/local/mycat/logs/wrapper.log

  2. vim复制粘贴导致多行出现#号解决办法

    在vim内复制多行假如复制的行带有#号会导致其他不带#号的行自动加# 解决办法,输入一下命令再粘贴即可 :set paste

  3. web框架初阶

    第一站 文件结构:web--- |--home.py #页面处理函数    |--index.py #主体函数 |--indexPlus.py #主体函数加强版 |--webdaem.py #通过we ...

  4. unity3d 嵌入iOS的 In App Purchase 应用程序内购买

    Unity做东西是快,但是有些功能是需要额外开发的,比如 IAP (In App Purchase,应用程序内购买) 还好unity提供了灵活的扩展功能,允许嵌入原生代码来做一些unity未实现的功能 ...

  5. Vue中ESlint配置文件.eslintrc文件

    很久没有分享和更新过了 今天就给大家分享一篇 Vue中ESlint配置文件.eslintrc文件详解吧 ------------------------------------------------ ...

  6. 前端手势控制图片插件书写二(transform矩阵的原理)

    上次解释了如何使用代码识别双指和单指操作及放大和旋转拖动操作.这次解释下css3的transform原理 一.transform矩阵原理 transform: matrix(a,b,c,d,e,f) ...

  7. kafka server.properties 配置文件详解(二)

    虽然在前面一部分我们启动了kafka集群,并通过控制台的方式实现了producer和consumer,但是我们还是了解一下kafka单个节点是的配置参数属性, 也只有了解了这些参数的配置,才能将kaf ...

  8. Android Studio中怎么使用DDMS工具

    随着android studio的广泛使用,开发人员对相关工具的使用需求更加凸显.昨天在一个android studio教程网站上,看到一篇有关DDMS工具使用的相关知识,感觉很不错,分享给大家,一起 ...

  9. spark调优篇-spark on yarn web UI

    spark on yarn 的执行过程在 yarn RM 上无法直接查看,即 http://192.168.10.10:8088,这对于调试程序很不方便,所以需要手动配置 配置方法 1. 配置 spa ...

  10. 适合新手的160个creakme(四)

    这题没有什么特殊字符串,Delphi写的,使用DeDeDark分析一下,找到几个特殊的事件 一个是KeyUp 一个是chkcode 还有就是中间区域的单击或是双击事件 直接跟进去这几个函数,然后找比较 ...