当前位置: 首页 > 知识库问答 >
问题:

持续读取java WatchEvents

利海阳
2023-03-14

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

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

我修改的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;
    }
}

我的客户:

import java.nio.file.attribute.*;
import java.nio.file.*;
import java.util.concurrent.TimeUnit;

public class newClient {
    public static void main(String[] args) throws IOException {

        Path folder = Paths.get(System.getProperty("user.dir"));
        WatchDir watcher = new WatchDir(folder, true);
        myTuple thisTuple;

    while (true) {
        thisTuple = watcher.processEvents();
        String event = thisTuple.getEvent();
        Path path = thisTuple.getPath();

        System.out.println(event+": "+path.toString());
    }
}
}

共有1个答案

於永寿
2023-03-14

您没有重置钥匙。再次阅读文档:

一旦事件被处理,消费者调用密钥的重置方法来重置密钥,这允许密钥被发信号并与进一步的事件重新排队。

大概在这里

       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;
 类似资料:
  • 它们还提供了一个警告:如果您能够持续部署到测试系统,有时也会使用术语“持续部署”。 这一切让我很困惑。任何更详细的解释(或附带一个例子)都是赞赏的!

  • 我的任务是通过Sustainsys(Kentor)库为我目前正在进行的项目设置SAML 2.0单点登录。这是我一直遵循的文档。该网站是一个webforms应用程序,因此我使用Sustainsys库的HTTPModule部分。我已将IDP(Okta)配置为将SAML2.0断言发送到文档中声明endpoint为/SAML或/SAML/Acs的网站。该网站是Kentico CMS网站,CMS提供了一个A

  • 我需要使用API V3获取YouTube内容长度。我的应用程序在API V3上运行良好,但现在不起作用了。 我发现了一个可行的例子,它确实有效: 学分: Youtube API v3 ,如何获取视频时长? 这将返回类似如下的时间格式。 我怎样才能把这个时间缩短到一个可读的时间呢。比如24:30?

  • translated_page: https://github.com/PX4/Devguide/blob/master/en/test_and_ci/continous_integration.md translated_sha: 95b39d747851dd01c1fe5d36b24e59ec865e323e PX4 Continuous Integration PX4 builds and

  • 问题内容: 如何在不创建MediaPlayer实例的情况下获得mp3曲目的持续时间?我只需要在mp3文件列表中显示mp3歌曲的长度,所以我认为我不应该为列表中的每个音轨创建MediaPlayer对象 还有一个: 有时MediaPlayer会返回错误的歌曲持续时间(我认为是错误的,因为这些文件的比特率是动态的)。如何获得正确的歌曲时长? 问题答案: 您可以使用MediaMetadataRetriev

  • 问题内容: 是否有任何PHP函数可以给我MP3持续时间。我看过ID 3的功能,但是在持续时间内我看不到任何东西,除此之外,id3是某种标签,在所有MP3中都不会出现,因此使用它没有任何意义。 问题答案: 这应该为您工作,请注意getduration函数:http ://www.zedwood.com/article/127/php-calculate- duration-of-mp3