Альтернативы ограничениям памяти Python Popen.communicate()? - программирование

Альтернативы ограничениям памяти Python Popen.communicate()?

У меня есть следующий фрагмент кода Python (работает v2.7), в результате которого MemoryError исключаются исключения, когда я работаю с большими (несколькими GB) файлами:

myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
myStdout, myStderr = myProcess.communicate()
sys.stdout.write(myStdout)
if myStderr:
    sys.stderr.write(myStderr)

При чтении документации к Popen.communicate() происходит некоторая буферизация:

Примечание Чтение данных буферизируется в памяти, поэтому не используйте этот метод, если размер данных является большим или неограниченным.

Есть ли способ отключить эту буферизацию или заставить кеш очищаться периодически во время процесса?

Какой альтернативный подход я должен использовать в Python для запуска команды, которая передает гигабайты данных в stdout?

Я должен отметить, что мне нужно обрабатывать выходные и потоки ошибок.

4b9b3361

Ответ 1

Я думаю, что нашел решение:

myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
for ln in myProcess.stdout:
    sys.stdout.write(ln)
for ln in myProcess.stderr:
    sys.stderr.write(ln)

Похоже, что мое использование памяти достаточно, чтобы справиться с задачей.

Обновление

Недавно я нашел более гибкий способ передачи потоков данных в Python с использованием потоков. Интересно, что Python настолько низок в чем-то, что скрипты оболочки могут делать это легко!

Ответ 2

То, что я бы, вероятно, сделал, вместо этого, если мне нужно было прочитать stdout для чего-то большого, отправляет его в файл при создании процесса.

with open(my_large_output_path, 'w') as fo:
    with open(my_large_error_path, 'w') as fe:
        myProcess = Popen(myCmd, shell=True, stdout=fo, stderr=fe)

Изменить: если вам нужно потоковое, вы можете попробовать создать файл-подобный объект и передать его в stdout и stderr. (Я еще не пробовал это.) Затем вы могли читать (запрос) из объекта, когда он записывается.