Подтвердить что ты не робот

Операции записи Atomic файлов (кросс-платформа)

Как создать операцию записи атомарного файла? Файл должен быть написан службой Java и прочитан скриптами python.
Для записи чтение намного больше, чем записи. Но запись происходит в партиях и, как правило, длинна. Размер файла составляет мегабайты.

Сейчас мой подход:

  • Запись содержимого файла во временный файл в тот же каталог
  • Удалить старый файл
  • Переименуйте файл temp в старое имя файла.

Это правильный подход? Как избежать ситуаций, когда старый файл удален, но новое имя файла еще не переименовано?

Предоставляют ли эти языки программирования (python и java) конструкции блокировки и избегают этой ситуации?

4b9b3361

Ответ 1

AFAIK no.

И причина в том, что для такой атомной операции это возможно, должна быть поддержка ОС в виде транзакционной файловой системы. И ни одна из основных операционных систем не предлагает транзакционную файловую систему.

РЕДАКТИРОВАТЬ. Я ошибаюсь, по крайней мере, для POSIX-совместимых систем. Syscall POSIX rename выполняет замену атома, если файл с целевым именем уже существует... как указано @janneb. Этого должно быть достаточно для оперативного выполнения операции OP.

Однако факт остается фактом: метод Java File.renameTo() явно не гарантированно является атомарным, поэтому он не обеспечивает кросс-платформенное решение проблемы OP.

EDIT 2. С Java 7 вы можете использовать java.nio.file.Files.move(Path source, Path target, CopyOption... options) с copyOptions и ATOMIC_MOVE. Если это не поддерживается (операционной системой/файловой системой), вы должны получить исключение.

Ответ 2

По крайней мере на платформах POSIX оставьте шаг 3 (удалите старый файл). В POSIX переименование внутри файловой системы гарантировано будет атомарным, а переименование поверх существующего файла заменяет его атомарно.

Ответ 3

Это классическая проблема производителя/потребителя. Вы должны решить эту проблему, используя переименование файлов, которое является атомарным в системах POSIX.

Ответ 4

В Linux, Solaris, Unix это легко. Просто используйте rename() из вашей программы или mv. Файлы должны находиться в одной файловой системе.

В Windows это возможно, если вы можете управлять обеими программами. LockFileEx. Для чтения откройте файл shared lock в файле блокировки. Для записи откройте файл exclusive lock в файле блокировки. Блокировка является странной в Windows, поэтому я рекомендую использовать для этого отдельный файл блокировки.

Ответ 6

Вы можете попробовать и использовать дополнительный файл, чтобы действовать как блокировка, но я не уверен, что это сработает нормально. (Это заставит вас создать проверку блокировки и повторить логику с обеих сторон, java и python)

Другим решением может быть не создание файлов вообще, возможно, вы могли бы заставить свой Java-процесс прослушивать порт и обслуживать данные оттуда, а не из файла?

Ответ 7

Попросите скрипты python запросить разрешение у службы. Пока служба пишет, она помещает блокировку в файл. Если блокировка существует, служба отклонит запрос python.