Альтернативы Python Popen.общаться() ограничения памяти?
у меня есть следующий кусок кода Python (работает v2.7) это приводит к MemoryError
исключения, создаваемые при работе с большими (несколько ГБ) файлами:
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
?
Я должен отметить, что мне нужно обрабатывать потоки вывода и ошибок.
2 ответов
Я думаю, что нашел решение:
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 настолько беден в чем-то, что скрипты оболочки могут делать так легко!
что я, вероятно, сделал бы вместо этого, если бы мне нужно было прочитать 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)
Edit: Если вам нужно потоковое, вы можете попробовать сделать файловый объект и передать его в stdout и stderr. (Хотя я не пробовал.) Затем вы можете прочитать (запрос) из объекта по мере его записи.