Java - как узнать, используется ли каталог другим процессом?

Я хочу использовать WatchService java 7 для отслеживания изменений в каталоге.
Кажется, он пытается заблокировать папку и выдает исключение в случае сбоя, но, похоже, не предоставляет никакого метода блокировки заранее / проверка, если он уже заблокирован.

Мне нужно знать, используется ли каталог в настоящее время другим процессом или нет. Поскольку я не могу заблокировать его или открыть для него поток (потому что это каталог), я ищу что-то более разумное, чем пытаться изменить его и заснуть в случае неудачи или попробовать/поймать со сном.

В идеале хотелось бы блокирующий вызов, пока он не доступен.

РЕДАКТИРОВАТЬ: я не могу получить FileLock в папке. Когда я пытаюсь заблокировать папку, я получаю «FileNotFoundException (доступ запрещен)». Поиск в Google предполагает, что вы не можете использовать этот объект в каталоге.

Регистрационный код:

WatchService watchService = path.getFileSystem().newWatchService()
path.register(watchService,
                    StandardWatchEventKinds.ENTRY_CREATE,
                    StandardWatchEventKinds.ENTRY_MODIFY,
                    StandardWatchEventKinds.ENTRY_DELETE)

Неудачный сценарий:
Допустим, я прослушиваю папку f для нового создания.
Если в ней создается подпапка g, я хочу прослушивать изменения в g. Однако, если я создам новую папку в f (в Windows), это не удастся, потому что Windows блокирует папку до тех пор, пока не будет задано имя.

Спасибо


person Gal    schedule 10.08.2013    source источник
comment
зачем вам знать, используется ли он другим процессом, если все, что вам нужно, это отслеживать его изменения?   -  person    schedule 10.08.2013
comment
поскольку регистрация метода (docs.oracle.com/javase/7/docs/api/java/nio/file/), который регистрирует изменения, создает исключение, если каталог используется.   -  person Gal    schedule 10.08.2013
comment
@Gal, можешь опубликовать код?   -  person boxed__l    schedule 10.08.2013
comment
Я добавил некоторый код и неудачный сценарий   -  person Gal    schedule 10.08.2013
comment
проверьте этот учебник и сравните с вашим кодом на наличие различий, возможно, вы что-то увидите: docs.oracle.com/javase/tutorial/essential/io/notification.html   -  person    schedule 10.08.2013
comment
@A.J., спасибо, но это не касается случая, когда папка используется другим процессом при попытке зарегистрироваться.   -  person Gal    schedule 10.08.2013
comment
The Watch Service API takes advantage of this support[native support for file change notification] where available. However, when a file system does not support this mechanism, the Watch Service will poll the file system, waiting for events. Думаю, проблема в этом   -  person boxed__l    schedule 10.08.2013
comment
@boxed__l, я могу слушать и получать события после регистрации; проблема в том, что я не могу зарегистрироваться в папке, которая используется другим процессом.   -  person Gal    schedule 10.08.2013
comment
какое исключение вы получаете? если это ошибка, потому что во время уведомления папка еще не названа в Windows, возможно, вы поймаете эту ошибку и проигнорируете ее (например, при этой ошибке проверьте, не установлено ли имя файлового объекта). скорее всего, после того, как вы закончите устанавливать имя в окнах, будет сгенерировано другое событие, на этот раз с полным именем. еще лучше, попробуйте не регистрироваться, если имя файла в уведомлении пустое или пустое, и продолжайте ждать.   -  person    schedule 10.08.2013
comment
@A.J., как я уже упоминал, ошибка в том, что файл используется другим процессом. У него есть имя, но когда вы создаете новую папку в Windows, она называется «Новая папка» и просит вас переименовать ее. прежде чем разблокировать папку. Прямо сейчас я использую try catch, но я бы предпочел что-то более элегантное.   -  person Gal    schedule 10.08.2013


Ответы (2)


Взято из здесь

File file = new File(fileName);
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
// Get an exclusive lock on the whole file
FileLock lock = channel.lock();
try {
    lock = channel.tryLock();
    // Ok. You get the lock
} catch (OverlappingFileLockException e) {
    // File is open by someone else
} finally {
    lock.release();
}
person RyPope    schedule 10.08.2013
comment
Я уже пробовал это, но всякий раз, когда я пытаюсь заблокировать файл, я получаю FileNotFoundException ‹имя папки› (отказано в доступе). - person Gal; 10.08.2013

После всех комментариев и поскольку ваша проблема связана с окнами, я хотел предложить следующую библиотеку:

http://jpathwatch.wordpress.com/

если почитать характеристики, то можно увидеть следующее:

Изменения в подкаталогах* (рекурсивный мониторинг)

это то, что вам нужно. кажется, он делает это за вас без необходимости вручную регистрировать каждый новый каталог. он ограничен выбранными платформами. а при проверке кажется что доступно только в винде!!!! см. здесь: http://jpathwatch.wordpress.com/documentation/features/

очень важной вещью является возможность аннулирования, когда отслеживаемый каталог становится недоступным. (используя службу java watch, если каталог отслеживается и переименовывается, вы все равно получаете события со старым путем !!)

Я думаю, что эта библиотека будет самой элегантной и сэкономит вам много кода для этого случая.

person Community    schedule 10.08.2013
comment
Спасибо, но я действительно искал решение своей первоначальной проблемы, которая заключалась в том, чтобы выяснить, используется ли каталог другим процессом. Я уже решил проблему ad-hoc, используя try-catch-sleep. - person Gal; 10.08.2013