file watch 監聽 目錄以及子目錄

public class FileWatchTest {

    private static final String PATH = "/Users/admin/manoo/gitbook/document-demo/";

    public static void main(String[] args) throws InterruptedException {
        final boolean[] stop = {false};
        WatchService watchService;
        try {
            Path path = Paths.get(PATH.trim());
            watchService = FileSystems.getDefault().newWatchService();  //創建watchService
            //註冊需要監控的事件,ENTRY_CREATE 文件創建,ENTRY_MODIFY 文件修改,ENTRY_MODIFY 文件刪除
            WatchEvent.Kind<?>[] kinds = {
                    StandardWatchEventKinds.ENTRY_CREATE,
                    StandardWatchEventKinds.ENTRY_MODIFY,
                    StandardWatchEventKinds.ENTRY_DELETE
            };

            registry(path.toFile(), watchService, kinds);
            Thread thread = new Thread(() -> {
                WatchKey watchKey = null;
                do{
                    try {
                        // Get a watch key. Three methods are provided:
                        //   poll                    Returns a queued key, if available. Returns immediately with a null value, if unavailable.
                        //   poll(long, TimeUnit)    Returns a queued key, if one is available.
                        //                                                 If a queued key is not immediately available, the program waits until the specified time.
                        //                           The TimeUnit argument determines whether the specified time is nanoseconds, milliseconds, or some other unit of time.
                        //   take                    Returns a queued key. If no queued key is available, this method waits.
                        watchKey = watchService.take();

                        for(WatchEvent<?> event:watchKey.pollEvents()){
                            WatchEvent.Kind<?> kind=event.kind();
                            Path eventPath=(Path)event.context();
                            System.out.println("dir/file "+ eventPath.toString()+" change: " + kind);
                        }
                        watchKey.reset();
                    } catch (InterruptedException ignored) {
                    }
                    System.out.println("目錄內容發生改變");
                }while(!stop[0]);
                System.out.println("thread is about to end");
            });
            thread.start();
        } catch (IOException e) {
            System.out.println("file watch start error: " + e.getMessage());
        }
        int count = 1000;
        while(count > 0) {
            count --;
            TimeUnit.SECONDS.sleep(1);
        }
        stop[0] = true;
    }

    private static void registry(File file, WatchService watchService, WatchEvent.Kind<?>[] kinds) throws IOException {
        if(watchService == null && file == null) {
            return;
        }

        if(file.isDirectory()) {
            Paths.get(file.toURI()).register(watchService, kinds);
            File[] files = file.listFiles();
            if(files != null) {
                for(File subFile: files) {
                    registry(subFile, watchService, kinds);
                }
            }
        }
    }
}

多一嘴

有如下的寫法, 但是JDK 8 尚未支持

public static void main(String[] args) throws InterruptedException {
        final boolean[] stop = {false};
        WatchService watchService;
        try {
            Path path = Paths.get(PATH.trim());
            watchService = FileSystems.getDefault().newWatchService();  //創建watchService
            //註冊需要監控的事件,ENTRY_CREATE 文件創建,ENTRY_MODIFY 文件修改,ENTRY_MODIFY 文件刪除
            WatchEvent.Kind<?>[] kinds = {
                    StandardWatchEventKinds.ENTRY_CREATE,
                    StandardWatchEventKinds.ENTRY_MODIFY,
                    StandardWatchEventKinds.ENTRY_DELETE
            };

            path.register(watchService, kinds, ExtendedWatchEventModifier.FILE_TREE);
            Thread thread = new Thread(() -> {
                WatchKey watchKey = null;
                do{
                    try {
                        // Get a watch key. Three methods are provided:
                        //   poll                    Returns a queued key, if available. Returns immediately with a null value, if unavailable.
                        //   poll(long, TimeUnit)    Returns a queued key, if one is available.
                        //                                                 If a queued key is not immediately available, the program waits until the specified time.
                        //                           The TimeUnit argument determines whether the specified time is nanoseconds, milliseconds, or some other unit of time.
                        //   take                    Returns a queued key. If no queued key is available, this method waits.
                        watchKey = watchService.take();

                        for(WatchEvent<?> event:watchKey.pollEvents()){
                            WatchEvent.Kind<?> kind=event.kind();
                            Path eventPath=(Path)event.context();
                            System.out.println("dir/file "+ eventPath+" change: " + kind);
                        }
                        watchKey.reset();
                    } catch (InterruptedException ignored) {
                    }
                    System.out.println("目錄內容發生改變");
                }while(!stop[0]);
                System.out.println("thread is about to end");
            });
            thread.start();
        } catch (IOException e) {
            System.out.println("file watch start error: " + e.getMessage());
        }
        int count = 1000;
        while(count > 0) {
            count --;
            TimeUnit.SECONDS.sleep(1);
        }
        stop[0] = true;
    }

關鍵一步是

path.register(watchService, kinds, ExtendedWatchEventModifier.FILE_TREE);

但是並沒有用

看到 java 源碼

	final SensitivityWatchEventModifier var11 = SensitivityWatchEventModifier.MEDIUM;
            if (var3.length > 0) {
                Modifier[] var12 = var3;
                var7 = var3.length;

                for(int var14 = 0; var14 < var7; ++var14) {
                    Modifier var9 = var12[var14];
                    if (var9 == null) {
                        throw new NullPointerException();
                    }

                    if (!(var9 instanceof SensitivityWatchEventModifier)) {
                        throw new UnsupportedOperationException("Modifier not supported");
                    }

                    var11 = (SensitivityWatchEventModifier)var9;
                }
            }

才明白現在只支持 SensitivityWatchEventModifier 而不支持 ExtendedWatchEventModifier

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章