5

、およびイベントWatchServiceのディレクトリ ツリーを監視する があります。問題は、 a のコンテキストがPath オブジェクトしか与えないことです。削除イベントでは、パスが通常のファイルのディレクトリを参照しているかどうかわかりません。ENTRY_CREATEENTRY_DELETEENTRY-MODIFYWatchEvent<?>

WatchKey key = null;

try {
    key = watcher.take();
} catch (InterruptedException e) {
    e.printStackTrace();
}

for (WatchEvent<?> event : key.pollEvents()) {
    if (event.kind() == StandardWatchEventKinds.OVERFLOW) {
        continue;
    }

    Path parent = (Path) key.watchable();
    Path p = parent.resolve((Path) event.context());

    for (DirectoryModifiedListener listener : listeners) {
        if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
            // only do this if p referred to a file, not a directory
            listener.onFileCreated(p);
        }
    }
}

p私の質問は、パスが削除されたファイルまたはディレクトリを参照しているかどうかを判断する方法ですか? これは、API が公開するものでも可能ですか?

4

1 に答える 1

3

Files.isDirectory(path) は、名前が示すように、リアルタイム チェックです。

Path オブジェクト (それぞれ、WindowsPath の実装) 自体には状態 (またはキャッシュされた履歴) はありません。パスのプレースホルダー以上のものではありません。

したがって、悲しい答えは、パスが削除された後、パスがディレクトリを参照していたかどうかを判断できないということです。

解決策の 1 つは、Path オブジェクトが存在する限りその種類を覚えておくことです。つまり、監視を開始する前にリストを収集します。

Path parent = Paths.get("/my/hotfolder");

Set<String> subdirs = new HashSet<String>();

for (Path p : Files.newDirectoryStream(parent)) {
    if (Files.isDirectory(p))
        subdirs.add(p.getFileName().toString());
}

ENTRY_CREATE を登録して、リストを最新の状態に保ちます

WatchKey key = hotfolder.register(watcher, ENTRY_CREATE, ENTRY_DELETE);

子オブジェクトがディレクトリであったかどうかを判断できるようになりました。

for (WatchEvent<?> event : key.pollEvents())
{
    if (event.kind() == StandardWatchEventKinds.OVERFLOW)
        continue;

    Path p = ((Path) key.watchable()).resolve((Path) event.context());

    String filename = p.getFileName().toString();

    if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE && Files.isDirectory(p))
        subdirs.add(filename);

    if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE)
    {
        if (subdirs.contains(filename))
        {
            for (DirectoryModifiedListener listener : listeners)
                listener.onFileDeleted(p);

            subdirs.remove(filename);
        }
    }
}
于 2013-07-06T00:02:35.897 に答える