Передать вывод из подпроцесса в файл, а затем прочитать его обратно - PullRequest
1 голос
/ 12 марта 2012

У меня есть скрипт Python, который запускает подпроцесс, чтобы получить некоторые данные и затем обработать их.Я пытаюсь добиться, чтобы данные были записаны в файл, а затем использовать данные из файла для обработки (причина в том, что подпроцесс медленный, но может меняться в зависимости от даты, времени и параметровЯ использую, и мне нужно часто запускать скрипт)

Я пробовал различные методы, включая открытие файла как w+ и попытку поиска начала после завершения записи, но, похоже, ничего не происходитработа - файл написан, но когда я пытаюсь прочитать из него обратно (используя file.readline()), я получаю EOF обратно.

Это то, что я пытаюсь сделать:

      myFile = open(fileName, "w")
      p = subprocess.Popen(args, stdout=myFile)
      myFile.flush()    # force the file to disk
      os.fsync(myFile)  # ..
      myFile.close()

      myFile = open(fileName, "r")
      while myFile.readline():
        pass # do stuff
      myFile.close()

Но даже если файл написан правильно (после запуска скрипта я могу увидеть содержимое файла), readline никогда не возвращает правильную строку.Как я уже сказал, я тоже пытался использовать тот же файловый объект и делать с ним seek(0), но безуспешно.Это работало только при открытии файла как r+, что не удается, если файл еще не существует.

Любая помощь будет принята с благодарностью.Кроме того, если есть более чистый способ сделать это, я открыт для этого:)

PS: я понимаю, что могу Popen и stdout в канал, читать из канала и затем писать строкувыровняйте данные в файл, как я это делаю, но я пытаюсь отделить создание файла данных от чтения.

Ответы [ 3 ]

2 голосов
/ 12 марта 2012

Подпроцесс почти наверняка не заканчивается, пока вы не попытаетесь прочитать файл. Фактически, вероятно, что подпроцесс даже не пишет ничего, прежде чем вы попытаетесь прочитать из файла. Для истинного разделения вам нужно будет выполнить подпроцесс записи во временный файл, а затем заменить файл, из которого вы читаете, так что вы либо читаете предыдущую или новую версию, но никогда не видите частично записанный файл из новая версия.

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

0 голосов
/ 12 марта 2012

@ Джеймс Айлетт указал мне правильный путь, похоже, что моя проблема заключалась в том, что подпроцесс. При запуске .flush () не было завершено открытие.

Решение состоит в том, чтобы вызвать p.wait () сразу после вызова subprocess.Popen, чтобы дать возможность завершиться основной команде. После этого .flush делает правильные вещи (поскольку все данные есть), и я могу приступить к чтению из файла.

Таким образом, приведенный выше код становится:

  myFile = open(fileName, "w")
  p = subprocess.Popen(args, stdout=myFile)

  p.wait()          # <-- Missing line

  myFile.flush()    # force the file to disk
  os.fsync(myFile)  # ..
  myFile.close()

  myFile = open(fileName, "r")
  while myFile.readline():
    pass # do stuff
  myFile.close()

И тогда все это работает!

0 голосов
/ 12 марта 2012

Это должно работать, если подпроцесс заканчивается вовремя (см. Ответ Джеймса).

Если вы хотите дождаться его завершения, добавьте p.wait() после вызова Popen.

Каков твой настоящий цикл while? while myFile.readline() кажется, что вы на самом деле ни для чего не экономите. Попробуйте это:

myFile = open(fileName, "r")
print myFile.readlines()
myFile.close()

Или, если вы хотите в интерактивном режиме проверить состояние вашей программы:

myFile = open(fileName, "r")
import pdb; pdb.set_trace()
myFile.close()

Затем вы можете делать такие вещи, как print myFile.readlines() после его остановки.

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