StandardWatchEvents.ENTRY_MODIFY срабатывает при изменении подпапки?

Пример: у меня есть рабочий стол с подпапкой «Рабочий стол/подраздел».

если зарегистрирован только рабочий стол и после запуска WatchService я изменяю содержимое подпапки ... должно ли это вызывать ENTRY_MODIFY или нет? Я пробовал, и это не так. Он работает только для изменения файла в зарегистрированной папке (в данном случае на рабочем столе).

Просто задаю этот вопрос, потому что в пробном экзамене для OCPJP7 говорится, что на самом деле даже изменение подпапки, такой как «Рабочий стол / подпрограмма», например удаление файла в «Рабочий стол / подпрограмма», должно вызвать событие.

Однако, еще раз, я попробовал это, и это не работает.

Вот код:

WatchKey key = ws.poll(5, TimeUnit.SECONDS);

if (key ==null)
{
    continue;
}
List<WatchEvent<?>> lista = key.pollEvents();

for (WatchEvent<?> event : lista)
{
    switch(event.kind().toString())
    {
    case "ENTRY_CREATE": System.out.println("There has been a creation over here: "+event.context());break;
    case "ENTRY_MODIFY": System.out.println("There has been a modification over here: "+event.context());break;
    case "ENTRY_DELETE": System.out.println("There has been a deletion over here: "+event.context());

    }

    key.reset();
}

Заранее спасибо.


person Rollerball    schedule 02.09.2013    source источник


Ответы (1)


WatchService просматривает только изменения файлов и папок в зарегистрированных Path.

Если вы зарегистрировались

WatchService service = FileSystems.getDefault().newWatchService();
Path path = Paths.get("/Desktop");
path.register(service, StandardWatchEventKinds.ENTRY_MODIFY);

Затем будет видно добавление папки в Desktop. Изменение файла в Desktop будет видно. Добавление папки в Desktop/Subs также будет видно, потому что папка Subs внутри Desktop была изменена. Однако изменение файла в Desktop/Subs не будет видно, поскольку этот путь не зарегистрирован в службе.

Вы всегда можете зарегистрировать все пути под Desktop рекурсивно

private void registerRecursive(final Path root) throws IOException {
    // register all subfolders
    Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
                return FileVisitResult.CONTINUE;
        }
    });
}

Я не пробовал в Linux, но в Windows работает следующее

public static void main(String[] args) throws Exception {   

    WatchService service = FileSystems.getDefault().newWatchService();
    Path path = Paths.get("/Desktop");
    path.register(service, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_CREATE);
    WatchKey key = null;
    while(true) {
        key = service.take();

        List<WatchEvent<?>> lista = key.pollEvents();

        for (WatchEvent<?> event : lista)
        {
            switch(event.kind().toString())
            {
            case "ENTRY_CREATE": System.out.println("There has been a creation over here: "+event.context());break;
            case "ENTRY_MODIFY": System.out.println("There has been a modification over here: "+event.context());break;
            case "ENTRY_DELETE": System.out.println("There has been a deletion over here: "+event.context());

            }

            key.reset();
        }
    }
}
person Sotirios Delimanolis    schedule 02.09.2013
comment
Я попытался добавить и файл, и каталог в Desktop/sub, и ENTRY.MODIFY ничего не вызвал. Однако это работает, если я изменяю файл на рабочем столе. Код, который я использую, опубликован выше. Я использую убунту 12.10 - person Rollerball; 02.09.2013
comment
@Rollerball Какие StandardWatchEventKinds вы объявили? - person Sotirios Delimanolis; 02.09.2013
comment
все они, если я изменяю файл на рабочем столе, это вызывает событие - person Rollerball; 02.09.2013
comment
только если я добавляю файл или удаляю файл/каталог в Desktop/Sub, это ничего не вызывает. - person Rollerball; 02.09.2013
comment
Вы должны зарегистрировать свой путь как path.register(service, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE);. Где path — это объект Path для /Desktop. Добавление или удаление файла в Desktop/Sub вызовет событие. Пожалуйста, проверьте правильность установки WatchService. - person Sotirios Delimanolis; 02.09.2013
comment
Дважды проверил, и я также сказал вам, что изменение файла на рабочем столе вызывает его. - person Rollerball; 02.09.2013
comment
Я думаю, что это может зависеть от операционной системы, я на Ubuntu 12.10 - person Rollerball; 02.09.2013
comment
@ROllerball В Windows, да, это запускает их с кодом, который я добавил в своем последнем редактировании. Я сомневаюсь, что Linux помешает этой функции. Я бы подумал, что это гарантируется API, даже если базовая реализация отличается. - person Sotirios Delimanolis; 02.09.2013
comment
мм вижу. У меня есть супер двойная проверка, и если я не использую рекурсивный способ. Он не срабатывает при изменении подкаталога зарегистрированного каталога.. в этот момент я хотел бы услышать другого пользователя, использующего linux - person Rollerball; 02.09.2013