Эквивалент Python для вывода файла трубопровода в gzip в Perl с использованием канала - PullRequest
9 голосов
/ 29 ноября 2011

Мне нужно выяснить, как записать вывод файла в сжатый файл на Python, как показано в двух строчках ниже:

open ZIPPED, "| gzip -c > zipped.gz";
print ZIPPED "Hello world\n";

В Perl это использует Unix gzip для сжатия всего, что вы печатаете, в дескриптор файла ZIPPED в файл "zipped.gz".

Я знаю, как использовать «import gzip», чтобы сделать это в Python следующим образом:

import gzip
zipped = gzip.open("zipped.gz", 'wb')
zipped.write("Hello world\n")

Однако это очень медленно. Согласно профилировщику, использование этого метода занимает 90% моего времени выполнения, поскольку я записываю 200 ГБ несжатых данных в различные выходные файлы. Я знаю, что файловая система может быть частью проблемы здесь, но я хочу исключить ее, используя вместо этого сжатие Unix / Linux. Это отчасти потому, что я слышал, что распаковка с использованием этого же модуля также медленная.

Ответы [ 3 ]

10 голосов
/ 29 ноября 2011

Предложение Кристофа об использовании модуля подпроцесса является подходящим ответом на этот вопрос.Однако мне не ясно, что это решит ваши проблемы с производительностью.Вы должны были бы измерить производительность нового кода, чтобы быть уверенным.

Чтобы преобразовать ваш пример кода:

import subprocess

p = subprocess.Popen("gzip -c > zipped.gz", shell=True, stdin=subprocess.PIPE)
p.communicate("Hello World\n")

Так как вам нужно отправить большие объемы данных в подпроцесс, вам следует рассмотреть возможность использования атрибута stdin объекта Popen.Например:

import subprocess

p = subprocess.Popen("gzip -c > zipped.gz", shell=True, stdin=subprocess.PIPE)
p.stdin.write("Some data")

# Write more data here...

p.communicate() # Finish writing data and wait for subprocess to finish

Вы также можете найти обсуждение на этот вопрос полезным.

5 голосов
/ 29 ноября 2011

Попробуйте что-то вроде этого:

from subprocess import Popen, PIPE
f = open('zipped.gz', 'w')
pipe = Popen('gzip', stdin=PIPE, stdout=f)
pipe.communicate('Hello world\n')
f.close()
2 голосов
/ 29 ноября 2011

Использование gzip-модуля является официальным способом сделать это, и маловероятно, что любой другой подход на чистом Python пойдет быстрее Это особенно верно, потому что размер ваших данных исключает параметры в памяти. Скорее всего, самый быстрый способ - записать полный файл на диск и использовать подпроцесс для вызова gz для этого файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...