Атомарные (кросс-платформенные) операции записи файла

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

Прямо сейчас мой подход:

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

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

Эти языки программирования (Python и Java) предлагают конструкции, чтобы заблокировать и избежать этой ситуации?

26
задан Quintin Par 13 January 2010 в 03:09
поделиться

6 ответов

Я думаю, что характеристикой, которая лучше определяет VIM по отношению к другим редакторам, является широкий спектр команд движения. Первое, что нужно научиться полноценно использовать VIM - это как можно меньше бить по клавишам со стрелками, и думать над текстом в терминах «блоки» вроде «предложение» «а» тэг «слово» «группа скобок».

Скажем, что у вас есть функция foo ($ bar, $ fooz) вы можете изменить параметры, просто разместив курсор в любом месте внутри скобок и нажав ci) (мнемоника: изменить внутреннюю скобку). Тот же образец относится и к другим командам: yank ( y ), delete ( d ) и так далее.

Я знаю, что это не объясняет всю «философию VIM», но объединение команд обычного режима с огромным количеством модификаторов движения - это то, что действительно заставило меня увидеть свет.

-121--4104001-
# Comment in the beginning of the file

Это делают по крайней мере встроенные модули python. (выясняется при помощи grep 'Copyright '/usr/lib64/python2.4/* .py )

-121--1455194-

АФАИК №

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

EDIT - Я ошибаюсь, по крайней мере, для систем, совместимых с POSIX. POSIX rename syscall выполняет атомарную замену, если файл с целевым именем уже существует... как указано @ janneb. Этого должно быть достаточно, чтобы оперировать ОП атомарно.

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

EDIT 2 - С помощью Java 7 можно использовать java.nio.file.Files.move (Источник пути, Цель пути, StartOption... options) вместе с (или ATOMIC _ MOVE ). Если это не поддерживается (ОС/файловой системой), следует получить исключение.

10
ответ дан 28 November 2019 в 17:19
поделиться

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

5
ответ дан 28 November 2019 в 17:19
поделиться

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

3
ответ дан 28 November 2019 в 17:19
поделиться

Попробуйте Java Filelock API

1
ответ дан 28 November 2019 в 17:19
поделиться

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

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

1
ответ дан 28 November 2019 в 17:19
поделиться

имеют разрешение запроса скриптов Python от службы. Хотя служба написана, это будет поместить блокировку в файл. Если замок существует, сервис отклонит запрос Python.

1
ответ дан 28 November 2019 в 17:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: