Использование mmap с popen

Мне нужно прочитать и обработать кучу ~40 МБ сжатых текстовых файлов, и мне нужно, чтобы это было сделано быстро и с минимальными затратами на ввод / вывод (поскольку тома также используются другими). Самый быстрый способ, который я нашел для этой задачи, выглядит следующим образом:

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) Как мне этого добиться?

Большое спасибо... все здесь были невероятно полезны уже! ~Nik

2 ответа

Решение

От mmap(2) справочная страница:

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

Вы не можете mmap потоки, только реальные файлы или анонимное пространство подкачки. Вам нужно будет читать из потока в память самостоятельно.

Трубы не являются mmapable.

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

и файловые операции канала не содержат mmap крюк.

Другие вопросы по тегам