Есть ли в Python простой способ создать файл, в который можно записать в одном потоке и прочитать в другом? - PullRequest
2 голосов
/ 27 декабря 2008

В написанной мной программе на python у меня есть поток, который перебирает большую структуру в памяти и постепенно записывает ее в файлоподобный объект. У меня есть другой поток, который берет файлоподобный объект и записывает его на диск. Есть ли простой способ соединить два, так что любой ввод данных из первого потока будет буферизован для второго?

В частности, я пытаюсь передать данные в subprocess.Popen (). Процесс будет читать из stdin, но вы не можете передать объект, подобный файлу, в Popen, потому что он вызывает stdin.fileno () и взрывается, если у вас нет реального файла.

Вместо этого вам нужно передать аргумент PIPE Попену, который позволяет вам использовать proc.stdin в качестве файлового объекта. Но если у вас уже есть файлоподобный объект, кажется, нет хорошего способа соединить их вместе.

Ответы [ 4 ]

4 голосов
/ 27 декабря 2008

Вы должны использовать модуль Queue для совместного использования последовательных данных между потоками. Вам придется создать файловый подкласс Queue, в котором .read и .write взаимно блокируют друг друга с промежуточным буфером.

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

2 голосов
/ 27 декабря 2008

Использование shutil s copyfileobj() Функция:

import shutil
import subprocess

proc = subprocess.Popen([...], stdin=subprocess.PIPE)

my_input = get_filelike_object('from a place not given in the question')

shutil.copyfileobj(my_input, proc.stdin)

Нет необходимости использовать темы.

1 голос
/ 27 декабря 2008

Я думаю, что в дизайне что-то не так, если у вас уже есть файловый объект, если вы хотите, чтобы ваши данные попали в подпроцесс. Затем вы должны договориться о том, чтобы они были записаны в подпроцесс в первую очередь, вместо того, чтобы записывать их сначала во что-то другое, похожее на файл. Кто бы ни записывал данные, он должен гибко определять поток вывода, и это должен быть канал подпроцесса.

В качестве альтернативы, если автор настаивает на создании своего собственного объекта потока, вы должны позволить ему завершить запись и только затем запускать подпроцесс, передавая его из результата первой записи. Например. если это объект StringIO, примите его значение после записи и запишите его в канал; здесь не требуется синхронизация потоков.

0 голосов
/ 27 декабря 2008

Мне не понятно, что ты пытаешься сделать, эхр. Это звучит как работа для обычного старого канала, который похож на файл. Я предполагаю, однако, что вы имеете в виду поток какой-то другой.

Это также звучит очень похоже на то, что вы хотите - это питон очередь , или, может быть, tempfile .

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