Может ли метод Java File "canWrite ()" поддерживать блокировку? - PullRequest
12 голосов
/ 23 сентября 2008

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 23 сентября 2008

Нет, canWrite не подходит для этой цели. В общем случае файл будет доступен для записи, даже если пишет другой процесс.

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

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

Так как в этом случае вы работаете исключительно с XML, поиск близкого тега будет работать, но он не является надежным & mdash; что, если после последней разметки есть комментарии, или автор пишет или просто не пишет корректный XML

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

4 голосов
/ 23 сентября 2008

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

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

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

2 голосов
/ 30 сентября 2009

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

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

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

1 голос
/ 23 сентября 2008

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

0 голосов
/ 23 сентября 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...