2

我需要读入并处理一堆约 40mb 的 gzip 压缩文本文件,并且我需要它以最小的 i/o 开销快速完成(因为这些卷也被其他人使用)。因此,我为此任务找到的最快方法如下所示:

def gziplines(fname): 
    f = Popen(['zcat', fname], stdout=PIPE)
    for line in f.stdout:
        yield line

进而:

for line in gziplines(filename)
    dostuff(line)

但我想做的(如果这更快?)是这样的:

def gzipmmap(fname): 
    f = Popen(['zcat', fname], stdout=PIPE)
    m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
    return m

可悲的是,当我尝试这个时,我收到了这个错误:

>>> m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
mmap.error: [Errno 19] No such device

即使,当我尝试时:

>>> f.stdout.fileno()
4

所以,我想我对这里发生的事情有一个基本的误解。:(

这两个问题是:

1) 这个 mmap 是否是将整个文件放入内存进行处理的更快方法?

2)我怎样才能做到这一点?

非常感谢……这里的每个人都已经非常乐于助人了!〜尼克

4

2 回答 2

4

mmap(2)手册页:

   ENODEV The  underlying  file system of the specified file does not sup-
          port memory mapping.

You cannot mmap streams, only real files or anonymous swap space. You will need to read from the stream into memory yourself.

于 2011-06-28T17:48:31.857 回答
1

Pipes aren't mmapable.

case MAP_PRIVATE:
      ...
if (!file->f_op || !file->f_op->mmap)
        return -ENODEV;

and pipe's file operations does not contain mmap hook.

于 2011-06-28T17:50:20.700 回答