Я хочу прочитать файл plan.txt
, сгенерированный планировщиком fast-down, для этого я использую subprocess
следующим образом:
import subprocess
search_options = "lama-first"
## Call Planner
cmd = [
"python3",
self.planner_path,
"--alias",
search_options,
"--plan-file",
self.plan_path,
self.domain_path,
self.problem_path,
]
## Read plan.txt
cmd2 = ["cat", self.plan_path]
subprocess.run(cmd, shell=False, stdout=subprocess.PIPE)
plan = []
try:
# Huge dealy to be sure that the plan is written to the txt file
time.sleep(1)
result2 = subprocess.run(cmd2, shell=False, stdout=subprocess.PIPE)
plan = result2.stdout.decode("utf-8")
except:
pass
Не могли бы вы сказать мне, как лучше всего убедиться, что план был записан на диск, прежде чем пытаться его прочитать, а не добавлять огромную временную задержку? заранее спасибо.
Нет необходимости вызывать time.sleep(...)
, потому что (1) subprocess.run
ждет завершения подпроцесса; (2) libc и ядро вместе гарантируют, что все ожидающие данные будут сброшены в выходные файлы при выходе из (под)процесса.
Модифицированный код выглядит так:
import os
import subprocess
try:
# Remove output of previous invocation.
os.remove(self.plan_path)
except OSError:
pass
search_options = "lama-first"
cmd = [
"python3",
self.planner_path,
"--alias",
search_options,
"--plan-file",
self.plan_path,
self.domain_path,
self.problem_path,
]
subprocess.run(cmd).check_returncode()
with open(self.plan_path, encoding = "utf-8") as f:
plan = f.read()
Некоторые комментарии к коду в вопросе:
subprocess.run(...)
вызовите .check_returncode()
, который прерывается, если подпроцесс не завершился успешно (с кодом выхода 0, что указывает на успех).cat
для чтения файла в Python.shell=False
, это значение по умолчанию, когда cmd является списком или кортежем.К сведению: из-за буферов и кешей ядра данные могут быть сброшены в постоянное хранилище (например, в файловую систему на жестком диске или твердотельном накопителе) через несколько секунд. Однако вам не нужно ждать этого в вашей программе, потому что ядро позаботится о том, чтобы любое последующее чтение, следующее за (сброшенной) записью в файл, увидит вывод записи, даже если вывод находится только в буферах или кешах. .
в некоторых случаях планировщик может не найти план, поэтому после выполнения plan.txt
файла subprocess.run(cmd).check_returncode()
не будет.
Вы можете использовать if os.path.isfile(self.plan_path):
, чтобы обнаружить это, или except FileError:
вокруг open
.
Не используйте
except: pass
. Он скрывает все исключения, поэтому вы не будете уведомлены о соответствующих ошибках.