什么时候使用mmap?

2020年10月5日 / 7次阅读 / Last Modified 2020年10月5日

记录一点自己的思考和测试,关于标准库中的mmap模块。

项目上遇到一个需求,要对超大文件进行读写,这个文件大到什么程度呢?有接近40G,notepad++等工具直接拒绝打开此文件。

用 r+ 模式打开文件,可以随意读写,但是要特别小心。readline是否能够使用,要看这个文件每行都多长,如果没有换行,就不能用,就算知道每行的大小,也要带个参数N来控制最大读取数量。readlines是肯定不能用的,就算带参数,也可能直接卡死!read(N)没问题,主要控制是N的大小。不过,这种方式写文件有限制,只能是覆盖的方式。如果用 a 模式打开文件,只能是追加的方式写入。

总之,传统读写文件的方式可以用,但是不够方便。速度也是个问题,传统的缓存IO方式,涉及到OS内核态的内存和进程虚拟空间内存的内容交换,对于超大文件而言,这种交换会浪费大量的CPU时间和内存。

mmap是另一个方式!它跳过了OS内核态的缓存,直接将文件在进程虚拟空间做map,默认对文件的打开方式是rb+。

从python官网上看mmap的介绍,生成的mmap对象,就像一个bytearray对象,可以直接用index的方式读写,可以slicing。同时,mmap对象还有一组类似文件操作的接口,read,readline,flush等等。即mmap对象兼具bytearray和file对象的功能。

比较方便的是mmap对象自带的find接口,直接对整个超大文件的内容进行查找。不过,这种方式对于40G的文件不行,程序依然卡死!文件太大了,最安全的方式依然是自己写代码来管理这段文件缓存,find step by step。。。

(测试了一会儿,貌似要使用offset参数来多次在不同的位置map文件的内容,否则不管是用find还是re,都一样的内存飙升......offset必须是mmap.PAGESIZE的整数倍,我在考虑写一个通用的接口来处理这类需求...)

用mmap对象写文件,依然是覆盖的方式。超大文件怎么在中间插入一行呢?没办法!!这就是为什么会有数据库的一个原因吧!如果全部数据都是一个个的文件,管理起来真的是个头疼的问题,于是先驱们将这一问题抽象出来统一解决,方案就是现在的数据库系统。

面对这样超大的文件,部分覆盖写入是可以的,一定要精确控制;实在要写一点东西进去,就用一个额外的文件吧。在这个额外的文件中记录清楚这些要写入内容的位置等信息,然后两个文件一起读!

mmap对象可以提高一定的系统效率,但是它不是绝对的,比如在40G文件中find一个字符串。

先就总结这些吧,以后再慢慢积累。

-- EOF --

本文链接:https://www.pynote.net/archives/2532

相关文章

    留言区

    《什么时候使用mmap?》有1条留言

    电子邮件地址不会被公开。 必填项已用*标注

    • 麦新杰

      mmap兼具file对象的接口,就可以指定read(N),每次读取的长度,在内存受限的情况下。 [回复]


    前一篇:
    后一篇:

    More


    ©Copyright 麦新杰 Since 2019 Python笔记

    go to top