简体   繁体   中英

Java WatchService does not report files when the parent directory is deleted

I have the following files and folders structure:

/root/

/root/pictures/

/root/pictures/picture1.jpg

/root/pictures/picture2.jpg

I registered two WatchServices, one for the /root/ folder and one for /root/pictures . For both I registered the events: ENTRY_CREATE , ENTRY_DELETE , ENTRY_MODIFY .

When I delete /root/pictures/ I expect to get one ENTRY_DELETE event for the deletion of the folder /root/pictures/ and two ENTRY_DELETE events for picture1.jpg and picture2.jpg . In fact I only get the ENTRY_DELETE event for /root/pictures/ . When I only delete picture1.jpg I get one delete event as expected.

Is that normal behaviour? How can I get the list of files that were inside a deleted folder with WatchService?

You did not show any code, so we don't know how you tried to implement it, but the following seems to work to get ENTRY_DELETE events for files within a directory if the directory itself is deleted (please note that it contains only one WatchService, for directory xxx/yyy; I have not included the other WatchService for directory xxx)

public class WatchServiceApp {

    public static void main(String[] args) throws IOException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path dirPath = Paths.get("/home/myuser/xxx/yyy");
        WatchKey watchKey = dirPath.register(
                watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

        while (true) {
            try {
                watchService.take();
            } catch (InterruptedException ex) {
                break;
            }

            List<WatchEvent<?>> watchEventList = watchKey.pollEvents();
            for (WatchEvent<?> watchEvent : watchEventList) {
                Path filePath = (Path) watchEvent.context();
                System.out.println("Event " + watchEvent.kind() + " for " + filePath.toString());
            }

            boolean watchKeyValid = watchKey.reset();
            if (!watchKeyValid) {
                break;
            }
        }
    }

}

Lets assume the directory xxx/yyy contains three files. First we delete individual file3 and get

Event ENTRY_DELETE for file3

then we delete the entire yyy directory and get

Event ENTRY_DELETE for file2
Event ENTRY_DELETE for file1

It looks like you does not deleted your directory finally. I mean, if you delete directory in Windows by key "delete", you will got an event for the deletion of the folder /root/pictures/. But your files will still alive in the trash can. If you will clear trash can - you will get ENTRY_DELETE events for picture1.jpg and picture2.jpg

From the documentation on WatchService (emphasis mine):

, or to use a primitive mechanism, such as polling, when a native facility is not available.,或者在本地工具不可用时使用原始机制,例如轮询。 [...]

Meaning that much of the way events are delivered is platform dependent. To your question, is that normal behaviour? The answer is: depends on the platform.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM