直接用open()读大文件慢是因为每次read()触发系统调用并多次拷贝数据到用户空间;而mmap通过内存映射实现零拷贝、按需加载,将文件映射为虚拟内存供直接访问,i/o由内核页缓存调度,对随机访问和重复读更高效。

为什么直接用 open() 读大文件会慢?
因为每次 read() 都触发系统调用,频繁拷贝数据到用户空间;而 mmap 把文件直接映射进进程虚拟内存,后续访问像操作内存数组一样,零拷贝、按需加载。但注意:它不减少磁盘 I/O,只是把 I/O 调度交给内核页缓存管理,对随机访问和重复读特别有效。
mmap.mmap() 的关键参数怎么选?
最常踩坑的是 length 和 access 参数:
-
length=-1是安全默认值,表示映射整个文件(实际长度由os.stat(file).st_size决定);显式传入长度必须 ≤ 文件大小,否则报OSError: [Errno 22] Invalid argument -
access=mmap.ACCESS_READ(只读)性能最好,且能映射超过可用物理内存的文件;若需写入,必须用ACCESS_WRITE,且文件需可写,否则抛PermissionError - Windows 下必须指定
fileno(即fd = os.open(...)),不能直接传文件路径;Linux/macOS 支持fileno=fd或直接传fd(推荐统一用os.open()获取)
如何安全地读取二进制结构化数据(如 float32 数组)?
别用 .read() —— mmap 对象支持切片和字节索引,但要配合 struct 或 numpy.frombuffer() 解析:
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
import mmap
import numpy as np
<p>with open('data.bin', 'rb') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:</p><h1>直接视作 uint8 数组(无拷贝)</h1><pre class="brush:python;toolbar:false;"> arr = np.frombuffer(mm, dtype=np.float32)
# 或按偏移读特定段:mm[1024:2048].cast('f')
⚠️ 注意:np.frombuffer() 返回的是只读视图;若需修改并同步回文件,得用 ACCESS_WRITE + np.ndarray 的 writeable=True(需手动设置 mm.flush() 持久化)
什么时候 mmap 反而更慢?
小文件(
- 未
close()或未flush()(写模式下)会导致数据丢失或程序退出时异常终止 - 多进程共享同一 mmap 区域需额外同步(如用
mmap.ACCESS_COPY防写冲突) - 32 位 Python 进程地址空间有限,映射 >2GB 文件可能失败(改用 64 位解释器)
真正省时间的地方,是反复随机访问固定偏移、或多个进程需共享只读数据——这时候 mmap 才真正发挥价值。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










