持续读取java WatchEvents

持续读取java WatchEvents,java,file-watcher,Java,File Watcher,我正在尝试在客户端和服务器之间同步两个文件夹及其子目录。我有一个修改过的版本,我已经在下面发布了。在我的客户机类中,我创建了一个WatchDir对象,并在无限循环中调用它的processEvents()方法 如果事件已注册,则该方法返回myTuple对象(包含事件类型和路径对象的结构),如果未注册,则返回null。问题是,这似乎只适用于目录中发生的第一个事件(即,如果我将一个文件添加到监视的文件夹中,我的WatchDirobject.processEvents()返回一个带有ENTRY\u CR

我正在尝试在客户端和服务器之间同步两个文件夹及其子目录。我有一个修改过的版本,我已经在下面发布了。在我的客户机类中,我创建了一个WatchDir对象,并在无限循环中调用它的
processEvents()
方法

如果事件已注册,则该方法返回
myTuple
对象(包含事件类型和路径对象的结构),如果未注册,则返回null。问题是,这似乎只适用于目录中发生的第一个事件(即,如果我将一个文件添加到监视的文件夹中,我的WatchDir
object.processEvents()
返回一个带有
ENTRY\u CREATE
事件的元组,并且不会为之后发生的其他文件添加/删除/修改返回另一个元组)。我希望连续调用
processEvents
(因此是无限while),每次发生某个事件时返回一个元组

我的修改WatchDir:

import static java.nio.file.StandardWatchEventKinds.*;
import static java.nio.file.LinkOption.*;
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class WatchDir {
    private final WatchService watcher;
    private final Map<WatchKey,Path> keys;
    private final boolean recursive;
    private boolean trace = false;

    public WatchDir(Path dir, boolean recursive) throws IOException {
        this.watcher = FileSystems.getDefault().newWatchService();
        this.keys = new HashMap<WatchKey,Path>(); //holds the key for each subdirectory
        this.recursive = true;

        registerAll(dir);
    }

    public void registerAll(Path start) throws IOException {
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                register(dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }

    public void register(Path dir) throws IOException {
        WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        keys.put(key, dir);
    }

    public myTuple processEvents() {
        WatchKey key;
        //while (true) {

            try {
                key = watcher.take();
            } catch (InterruptedException e) {
                return new myTuple("INTERRUPTED", null);
            }

            Path dir = keys.get(key); //get next subdirectory path
            if (dir == null)
                return new myTuple("NULL DIRECTORY", null);

            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind kind = event.kind();
                WatchEvent<Path> ev = cast(event);
                Path name = ev.context();
                Path child = dir.resolve(name);

                return new myTuple(event.kind().name(), child);
            }
            return null;
        //}
    }

    @SuppressWarnings("unchecked")
    static <T> WatchEvent<T> cast(WatchEvent<?> event) {
        return (WatchEvent<T>)event;
    }
}

你不需要重置钥匙。请再读一遍:

处理完事件后,使用者将调用密钥的 重置方法,重置钥匙,使钥匙发出信号,并 已重新排队等待其他事件

可能在这里

       for (WatchEvent<?> event : key.pollEvents()) {
            WatchEvent.Kind kind = event.kind();
            WatchEvent<Path> ev = cast(event);
            Path name = ev.context();
            Path child = dir.resolve(name);

            return new myTuple(event.kind().name(), child);
        }
        key.reset();
        return null;
for(WatchEvent事件:key.pollEvents()){
WatchEvent.Kind-Kind=event.Kind();
WatchEvent ev=铸造(事件);
路径名=ev.context();
路径子项=目录解析(名称);
返回新的myTuple(event.kind().name(),child);
}
键。重置();
返回null;

为了避免返回for循环,我不得不对代码进行了一些修改,但我缺少的正是重置。谢谢
       for (WatchEvent<?> event : key.pollEvents()) {
            WatchEvent.Kind kind = event.kind();
            WatchEvent<Path> ev = cast(event);
            Path name = ev.context();
            Path child = dir.resolve(name);

            return new myTuple(event.kind().name(), child);
        }
        key.reset();
        return null;