python mmap

张开发
2026/4/7 3:46:44 15 分钟阅读

分享文章

python mmap
# 聊聊Python里的mmap把文件当内存用平时处理文件的时候大多数人想到的都是open、read、write这些常规操作。但如果你需要处理特别大的文件或者想在多个进程间共享数据常规的文件操作就显得有些力不从心了。这时候可以看看mmap这个模块它提供了一种不太一样的文件处理思路。它到底是什么mmap的全称是memory-mapped files翻译过来叫内存映射文件。这个名字听起来有点技术化但其实概念挺直观的。想象一下你在看一张很大的地图这张地图铺满了整张桌子。你不需要把整张地图都拿起来看只需要走到桌子的某个位置低头就能看到那部分区域。mmap做的事情就类似——它把磁盘上的文件“映射”到内存的地址空间里让你可以像访问内存一样访问文件内容而不需要真的把整个文件都读到内存里。在Python里mmap模块就是对操作系统这个功能的封装。不同操作系统底层实现不太一样但Python的接口基本统一用起来还算方便。它能解决什么问题最直接的用途就是处理大文件。如果你有个几十GB的日志文件要分析用read()全部读到内存里显然不现实。用mmap的话你可以只映射文件的一部分或者虽然映射了整个文件但操作系统会按需加载实际占用的物理内存并不会那么大。另一个重要场景是进程间通信。多个Python进程可以映射同一个文件然后通过读写这个共享的内存区域来交换数据。这比用socket或者管道要简单直接特别是数据量大的时候。还有些比较特殊的用途比如某些数据库引擎用mmap来加速数据访问或者一些科学计算程序用它来处理超大的数据文件。总的来说当你需要频繁随机访问大文件或者需要在进程间共享大量数据时mmap就值得考虑了。怎么用起来用mmap之前得先打开文件这跟普通文件操作一样。不过要注意打开模式通常需要可读可写的话就用rb模式。importmmapwithopen(data.bin,rb)asf:# 创建内存映射mmmmap.mmap(f.fileno(),0)# 现在可以像操作字节串一样操作文件内容了datamm[100:200]# 读取100到200字节的内容mm[500:600]bx*100# 写入100个x# 修改会同步到文件mm.flush()# 用完记得关闭mm.close()这里有几个参数需要注意。length参数指定映射多少字节0表示映射整个文件。access参数控制访问权限比如mmap.ACCESS_READ是只读mmap.ACCESS_WRITE是可写写操作会同步到文件mmap.ACCESS_COPY是写时复制修改不会写回文件。如果是进程间共享每个进程都需要映射同一个文件。第一个进程创建文件并映射后面的进程直接映射就行。操作系统会保证数据的一致性。一些实际使用中的细节虽然mmap用起来简单但有些细节不注意容易出问题。文件大小是个需要关注的点。如果你映射的文件可能会增长最好预留足够的空间。可以在创建映射时指定一个比当前文件大的长度mmap会自动扩展文件。但要注意扩展文件的操作在某些系统上可能比较耗时。性能方面mmap在小数据量随机访问时表现很好因为避免了系统调用的开销。但如果是顺序读写大块数据传统的read/write可能更快因为少了缺页中断的开销。错误处理也不能忽视。mmap操作可能会抛出各种异常比如文件不存在、权限不足、内存不足等等。实际使用中最好加上适当的异常处理。还有个容易忽略的问题是修改了映射区域后数据不会立即写回磁盘除非调用flush()或者映射被关闭。如果程序意外退出可能会丢失数据。对于重要数据可以考虑定期flush或者用msync()强制同步。和其他技术的对比和传统的文件IO相比mmap最大的优势是减少了数据拷贝次数。普通read()需要把数据从内核缓冲区拷贝到用户空间而mmap直接让用户程序访问内核缓冲区少了一次拷贝。对于大文件这个优势比较明显。和共享内存相比mmap的优点是数据有文件作为后备存储进程退出后数据不会丢失。而且文件可以跨机器共享通过网络文件系统适用场景更广。缺点是性能可能比纯内存的共享内存稍差一些。在多进程环境下mmap比用Queue或者Pipe传输大量数据要高效因为不需要序列化和反序列化。但同步问题需要自己解决比如用锁或者信号量。Python标准库里还有个array模块它支持内存视图但只能处理内存中的数据不能直接映射文件。如果需要文件持久化还是得用mmap。最后说几句mmap不是银弹它适合特定的场景。如果你需要随机访问大文件或者要在进程间共享大量数据可以试试它。但如果只是顺序读写小文件传统的文件操作可能更简单直接。实际项目中用mmap的话建议先在小规模数据上测试确认没问题再应用到生产环境。特别是多进程共享的时候要仔细考虑同步和一致性问题。Python的mmap接口设计得还算友好但底层毕竟是系统调用不同平台的行为可能略有差异。如果代码需要跨平台运行最好在各个平台上都测试一下。工具本身没有好坏关键看用在什么地方。了解每个工具的特点才能在合适的时候做出合适的选择。mmap就是这样一种工具——平时可能用不上但真遇到合适的问题时它能提供一种简洁高效的解决方案。

更多文章