为了账号安全,请及时绑定邮箱和手机立即绑定

我可以通过WatchService监视单个文件的更改(不是整个目录)吗?

我可以通过WatchService监视单个文件的更改(不是整个目录)吗?

侃侃尔雅 2019-10-17 15:04:28
当我尝试注册文件而不是目录时java.nio.file.NotDirectoryException。我可以听一个文件更改,而不听整个目录吗?
查看完整描述

3 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

只需过滤目录中所需文件的事件即可:


final Path path = FileSystems.getDefault().getPath(System.getProperty("user.home"), "Desktop");

System.out.println(path);

try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {

    final WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

    while (true) {

        final WatchKey wk = watchService.take();

        for (WatchEvent<?> event : wk.pollEvents()) {

            //we only register "ENTRY_MODIFY" so the context is always a Path.

            final Path changed = (Path) event.context();

            System.out.println(changed);

            if (changed.endsWith("myFile.txt")) {

                System.out.println("My file has changed");

            }

        }

        // reset the key

        boolean valid = wk.reset();

        if (!valid) {

            System.out.println("Key has been unregisterede");

        }

    }

}

在这里,我们检查更改后的文件是否为“ myFile.txt”,如果已更改则执行任何操作。


查看完整回答
反对 回复 2019-10-17
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

其他答案是正确的,您必须监视目录并筛选特定文件。但是,您可能希望线程在后台运行。接受的答案可以无限期地阻止,watchService.take();并且不会关闭WatchService。适用于单独线程的解决方案可能如下所示:


public class FileWatcher extends Thread {

    private final File file;

    private AtomicBoolean stop = new AtomicBoolean(false);


    public FileWatcher(File file) {

        this.file = file;

    }


    public boolean isStopped() { return stop.get(); }

    public void stopThread() { stop.set(true); }


    public void doOnChange() {

        // Do whatever action you want here

    }


    @Override

    public void run() {

        try (WatchService watcher = FileSystems.getDefault().newWatchService()) {

            Path path = file.toPath().getParent();

            path.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);

            while (!isStopped()) {

                WatchKey key;

                try { key = watcher.poll(25, TimeUnit.MILLISECONDS); }

                catch (InterruptedException e) { return; }

                if (key == null) { Thread.yield(); continue; }


                for (WatchEvent<?> event : key.pollEvents()) {

                    WatchEvent.Kind<?> kind = event.kind();


                    @SuppressWarnings("unchecked")

                    WatchEvent<Path> ev = (WatchEvent<Path>) event;

                    Path filename = ev.context();


                    if (kind == StandardWatchEventKinds.OVERFLOW) {

                        Thread.yield();

                        continue;

                    } else if (kind == java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY

                            && filename.toString().equals(file.getName())) {

                        doOnChange();

                    }

                    boolean valid = key.reset();

                    if (!valid) { break; }

                }

                Thread.yield();

            }

        } catch (Throwable e) {

            // Log or rethrow the error

        }

    }

}

我尝试从公认的答案和本文进行工作。您应该能够与此线程一起使用new FileWatcher(new File("/home/me/myfile")).start()并通过调用该线程将其停止stopThread()。


查看完整回答
反对 回复 2019-10-17
  • 3 回答
  • 0 关注
  • 646 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信