如何从mmapped文件中读取行?

Max*_*ler 21 python text mmap file

似乎mmap接口只支持readline().如果我尝试迭代对象,我会得到字符而不是完整的行.

什么是逐行读取mmap文件的"pythonic"方法?

import sys
import mmap
import os


if (len(sys.argv) > 1):
  STAT_FILE=sys.argv[1]
  print STAT_FILE
else:
  print "Need to know <statistics file name path>"
  sys.exit(1)


with open(STAT_FILE, "r") as f:
  map = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
  for line in map:
    print line # RETURNS single characters instead of whole line
Run Code Online (Sandbox Code Playgroud)

Sve*_*ach 30

迭代一行的最简洁方法mmap

with open(STAT_FILE, "r+b") as f:
    map_file = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
    for line in iter(map_file.readline, b""):
        # whatever
Run Code Online (Sandbox Code Playgroud)

请注意,在Python 3中,sentinel参数iter()必须是类型bytes,而在Python 2中它必须是a str(即""代替b"").

  • 我不知道`iter`采用了这个`callable` /`sentinel`参数对.+1并删除了我的答案,赞成这一个. (3认同)

hoc*_*chl 15

我修改了你的例子:

with open(STAT_FILE, "r+b") as f:
        m=mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
        while True:
                line=m.readline()
                if line == '': break
                print line.rstrip()
Run Code Online (Sandbox Code Playgroud)

建议:

希望这可以帮助.

编辑:我在Linux上进行了一些时序测试,因为评论让我好奇.下面是对137MB文本文件上5次连续运行的时序进行比较.

普通文件访问:

real    2.410 2.414 2.428 2.478 2.490
sys     0.052 0.052 0.064 0.080 0.152
user    2.232 2.276 2.292 2.304 2.320
Run Code Online (Sandbox Code Playgroud)

mmap 文件访问:

real    1.885 1.899 1.925 1.940 1.954
sys     0.088 0.108 0.108 0.116 0.120
user    1.696 1.732 1.736 1.744 1.752
Run Code Online (Sandbox Code Playgroud)

这些时间不包括print声明(我将其排除在外).根据这些数字,我会说内存映射文件访问速度要快得多.

编辑2:使用python -m cProfile test.py我得到以下结果:

5432833    2.273    0.000    2.273    0.000 {method 'readline' of 'file' objects}
5432833    1.451    0.000    1.451    0.000 {method 'readline' of 'mmap.mmap' objects}
Run Code Online (Sandbox Code Playgroud)

如果我没有弄错的话,那就mmap快一点了.

此外,它似乎not len(line)表现得比line == '',至少这是我解释探查器输出的方式.

  • 我只是在程序中注释掉了打印内容,然后执行了10次time test.py时间,然后取了5个中间值。检查python -m cProfile test.py的结果会很有趣。 (2认同)