Java как получить события символической ссылки WatchService? - PullRequest
0 голосов
/ 04 августа 2020

У меня есть несколько вопросов относительно WatchService API. Вот мой код:

package test;

import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Main {
    public static void main(String[] args) throws Exception {
        WatchService watchService = FileSystems.getDefault().newWatchService();

        Path path = Paths.get("/tmp/a");
        WatchKey key1 = path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
        Path path2 = Paths.get("/tmp/b");
        WatchKey key2 = path2.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);

        System.out.println(key1.isValid()); // true
        System.out.println(key2.isValid()); // true

        WatchKey key;
        while ((key = watchService.take()) != null) {
            for (WatchEvent<?> event : key.pollEvents()) {
                Path dir = (Path) key.watchable();
                Path fullPath = dir.resolve((Path) event.context());
                File absPath = fullPath.toFile().getAbsoluteFile();
                System.out.println("Event kind:" + event.kind() + ". File affected: " + absPath + ".");
            }
            key.reset();
        }
    }
}

Я слежу за папками /tmp/a и /tmp/b, но b является символической ссылкой на a, т.е. я запустил ln -s /tmp/a /tmp/b.

Мои вопросы:

  1. Можно ли получить события изменения файла для /tmp/a и /tmp/b? Используя приведенный выше код, я получаю события только для /tmp/a. Например, если я запускаю touch /tmp/a/file1.txt, он печатает:
Event kind:ENTRY_CREATE. File affected: /tmp/a/file1.txt.
Event kind:ENTRY_MODIFY. File affected: /tmp/a/file1.txt.

Затем, когда я запускаю touch /tmp/b/file2.txt (используя b вместо a):

Event kind:ENTRY_CREATE. File affected: /tmp/a/file2.txt.
Event kind:ENTRY_MODIFY. File affected: /tmp/a/file2.txt.

Мне нужны события для обеих папок /tmp/a и /tmp/b, возможно ли это? Или мне придется делать это вручную, создав две карты (одна для сопоставления исходных папок с папками символических ссылок, а другая для сопоставления папок с символическими ссылками с исходными папками)?

Если я вызываю path.register(...) и path2.register(...) (как я сделал в моем примере кода), какой Path возвращается из WatchKey.pollEvents()? Это исходный путь или символическая ссылка? Или это основано на том, по какому пути я звоню register() первым? В моем примере я сначала регистрирую /tmp/a. Это причина, по которой я получаю события только для этого /tmp/a, а не /tmp/b?

Есть ли у вас какие-либо улучшения / предложения Я могу улучшить свой код WatchService?

Я использую Java 11 на CentOS 6.

Спасибо!

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