2015-07-09 5 views
2

Мне нужно отслеживать определенную папку для новых файлов, которые мне нужно обработать. У меня следующие требования:Папка монитора Java для файлов

  1. Имена файлов являются порядковыми номерами. Мне нужно обработать каждый файл по порядку. (Наименьшее число во-первых, нет гарантии, что каждый порядковый номер существует. Например: 1,2,5,8,9
  2. Если файлы уже существуют в папке во время запуска, мне необходимо обработать их напрямую
  3. Мне нужно гарантия того, что я только обрабатывать каждый файл один раз
  4. мне нужно, чтобы избежать чтения неполных файлов (которые все еще скопированные)
  5. служба должна быть надежной конечно ...

что является наиболее распространенным способом выполнить это?

Я использую Java SE7 и Spring 4.

Я уже смотрел WatchService Java 7, но, похоже, у него проблемы с обработкой уже существующих файлов во время запуска и избежать обработки неполных файлов.

+0

https://docs.oracle.com/javase/tutorial/essential/io/notification.html - И вам нужно будет выполнить свою собственную персистенцию или какой-либо вид, чтобы распознать уже обработанные файлы. Либо переместите их в другой каталог, либо поместите имя файла в базу данных и проверите против него, и т. Д. – SnakeDoc

+0

Учебник, о котором вы говорите, относится к WatchService, упомянутому в моем вопросе. Как вы справитесь с «неполными файлами», событие «создать» будет запущено до того, как файл будет завершен. Также как вы решаете проблему с чтением файлов, которые уже присутствуют в папке, во время запуска приложения? –

+1

Что касается неполной проблемы с файлом, вам необходимо координировать работу с приложением, которое копирует/записывает файл.Общий способ - получить на нем FileLock, предполагая, что приложение для записи хорошо себя ведет, а используемая ОС поддерживает блокировку файлов. В противном случае у вас может быть приложение для записи сначала записать файл в имя файла temp (с другим суффиксом), а затем его атомарно перемещать в расширения файлов, которые вы выполняете (большинство ОС поддерживают это). В качестве последнего средства вы также можете отслеживать файл в течение короткого периода времени для изменения размера файла (что явно не идеально). –

ответ

1

Сборка комментариев в ответ.

Самый простой способ проанализировать файлы в правильном порядке - загрузить весь список файлов каталога в массив/список, а затем отсортировать список с помощью соответствующего компаратора. Например. Загрузите файлы с File.list() или File.listFiles().

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

Чтобы избежать чтения неполных файлов вы должны приобрести эксклюзивный FileLock (через FileChannel, который вы можете получить от FileOutputStream или FileInputStream, однако вы не можете быть в состоянии получить эксклюзивную блокировку от FileInputStream) на файл. Предполагая, что используемая ОС поддерживает блокировку файлов (какие современные операционные системы делают), и приложение, записывающее файл, хорошо себя ведет и удерживает блокировку (надеюсь, это так), то как только вы сможете получить блокировку, вы знаете, что файл завершен.

Если по какой-либо причине вы не можете полагаться на блокировку файлов, то вам необходимо сначала написать программу записи во временный файл (возможно, с другим расширением), а затем атомарно переместить/переименовать файл (атомный для большинства ОС, если в той же файловой системе/разделе), или отслеживать файл в течение определенного периода времени, чтобы узнать, написаны ли дополнительные байты (не самая надежная методология).