Может ли метод файла Java «canWrite()» поддерживать блокировку?

StackOverflow https://stackoverflow.com/questions/122282

  •  02-07-2019
  •  | 
  •  

Вопрос

У меня есть приложение Java, которое отслеживает папку на предмет входящих XML-файлов.Когда обнаруживается новый файл, мне нужно проверить, что файл в данный момент не обновляется и закрыт.Моя мысль состоит в том, чтобы использовать Файл.canWrite() чтобы проверить это.Есть ли какие-либо проблемы с этим?Это хороший способ проверить, что файл полностью записан?

Другие идеи, которые я подбрасываю:

  • Проанализируйте входящий файл XML и проверьте, что есть закрывающая тег.
  • Проверьте символ EoF.

Я просто не уверен, что какой-либо из этих методов справится со всеми сценариями.

Это было полезно?

Решение

Нет, canWrite для этой цели не подходит.Обычно файл будет доступен для записи, даже если его записывает другой процесс.

Вам нужен протокол более высокого уровня для координации блокировки.Если вы планируете использовать этот код на одной платформе, вы можете использовать Функция FileLock от NIO.Но внимательно прочитайте документацию и обратите внимание, что на многих платформах блокировка носит лишь рекомендательный характер.

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

Поскольку в этом случае вы работаете исключительно с XML, поиск закрывающего тега будет работать, но он не является надежным — что, если после окончательной разметки есть комментарии, или писатель или просто не пишет действительный XML?

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

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

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

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

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

Одна вещь, которая, по -видимому, работает в Windows, - это - создать объект файла (), который представляет рассматриваемый файл (используя конструктор с полным именем файла) - создайте второй идентичный объект файла, одинаково.- Попробуйте firstFile.renameTo(второй файл)

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

И поскольку имя файла nw = старому имени файла, это не создает никакой другой работы.

Насколько мне известно, невозможно узнать, есть ли в данный момент у другого процесса открытый дескриптор файла из Java.Один из вариантов — использовать FileLock класс из нового io.Это поддерживается не на всех платформах, но если файлы являются локальными и процесс записи файла сотрудничает, это должно работать на любой платформе, поддерживающей блокировки.

Если вы управляете и читателем, и писателем, то потенциальным методом блокировки будет создание блокировки каталог -- обычно это атомарная операция -- для продолжительности процесса чтения и записи.Если вы выберете этот тип подхода, вам придется управлять потенциальным сбоем процесса, приводящим к «зависанию» каталога блокировки.

Как упоминал Cheekysoft, файлы не являются атомарными и плохо подходят для блокировки.

Если вы не контролируете средство записи (например, если оно создается FTP-демоном), тогда лучшими вариантами будут метод переименования или метод задержки по времени.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top