Как убедиться, что файл был записан на диск перед его чтением

Я хочу прочитать файл 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

Не могли бы вы сказать мне, как лучше всего убедиться, что план был записан на диск, прежде чем пытаться его прочитать, а не добавлять огромную временную задержку? заранее спасибо.

Не используйте except: pass. Он скрывает все исключения, поэтому вы не будете уведомлены о соответствующих ошибках.

pts 21.02.2023 03:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет необходимости вызывать 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, что указывает на успех).
  • Не используйте кроме: pass. Он скрывает все исключения, поэтому вы не будете уведомлены о соответствующих ошибках.
  • Для простоты и переносимости (например, в Windows) используйте open(...) + read(), а не cat для чтения файла в Python.
  • Не нужно указывать shell=False, это значение по умолчанию, когда cmd является списком или кортежем.

К сведению: из-за буферов и кешей ядра данные могут быть сброшены в постоянное хранилище (например, в файловую систему на жестком диске или твердотельном накопителе) через несколько секунд. Однако вам не нужно ждать этого в вашей программе, потому что ядро ​​позаботится о том, чтобы любое последующее чтение, следующее за (сброшенной) записью в файл, увидит вывод записи, даже если вывод находится только в буферах или кешах. .

в некоторых случаях планировщик может не найти план, поэтому после выполнения plan.txt файла subprocess.run(cmd).check_returncode() не будет.

Bilal 21.02.2023 04:04

Вы можете использовать if os.path.isfile(self.plan_path):, чтобы обнаружить это, или except FileError: вокруг open.

pts 21.02.2023 12:25

Другие вопросы по теме