WatchService 和 SwingWorker:如何正确执行?

2024-04-16

WatchService 听起来像是一个令人兴奋的想法......不幸的是,它似乎像教程/api 中警告的那样低级,而且并不真正适合 Swing 事件模型(或者我错过了一些明显的东西,非零概率

获取代码来自教程中的 WatchDir 示例 http://download.oracle.com/javase/tutorial/essential/io/notification.html(简化为仅处理单个目录),我基本上结束了

  • 扩展 SwingWorker
  • 在构造函数中进行注册操作
  • 将等待按键的无限循环放入 doInBackground
  • 通过 key.pollEvents() 检索时发布每个 WatchEvent
  • 通过将删除/创建的文件作为 newValue 触发 propertyChangeEvents 来处理块

    @SuppressWarnings("unchecked")
    public class FileWorker extends SwingWorker<Void, WatchEvent<Path>> {
    
        public static final String DELETED = "deletedFile";
        public static final String CREATED = "createdFile";
    
        private Path directory;
        private WatchService watcher;
    
        public FileWorker(File file) throws IOException {
            directory = file.toPath();
            watcher = FileSystems.getDefault().newWatchService();
            directory.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        }
    
        @Override
        protected Void doInBackground() throws Exception {
            for (;;) {
                // wait for key to be signalled
                WatchKey key;
                try {
                    key = watcher.take();
                } catch (InterruptedException x) {
                    return null;
                }
    
                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();
                    // TBD - provide example of how OVERFLOW event is handled
                    if (kind == OVERFLOW) {
                        continue;
                    }
                    publish((WatchEvent<Path>) event);
                }
    
                // reset key return if directory no longer accessible
                boolean valid = key.reset();
                if (!valid) {
                    break;
                }
            }
            return null;
        }
    
        @Override
        protected void process(List<WatchEvent<Path>> chunks) {
            super.process(chunks);
            for (WatchEvent<Path> event : chunks) {
                WatchEvent.Kind<?> kind = event.kind();
                Path name = event.context();
                Path child = directory.resolve(name);
                File file = child.toFile();
                if (StandardWatchEventKinds.ENTRY_DELETE == kind) {
                    firePropertyChange(DELETED, null, file);
                } else if (StandardWatchEventKinds.ENTRY_CREATE == kind) {
                    firePropertyChange(CREATED, null, file);
                }
            }
        }
    
    }
    

基本思想是让使用代码幸福地不知道粘糊糊的细节:它监听属性更改和 f.i.根据需要更新任意模型:

    String testDir = "D:\\scans\\library";
    File directory = new File(testDir);
    final DefaultListModel<File> model = new DefaultListModel<File>();
    for (File file : directory.listFiles()) {
        model.addElement(file);
    }
    final FileWorker worker = new FileWorker(directory);
    PropertyChangeListener l = new PropertyChangeListener() {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (FileWorker.DELETED == evt.getPropertyName()) {
                model.removeElement(evt.getNewValue());
            } else if (FileWorker.CREATED == evt.getPropertyName()) {
                model.addElement((File) evt.getNewValue());
            }
        }
    };
    worker.addPropertyChangeListener(l);
    JXList list = new JXList(model);

貌似可以用,但是感觉不舒服

  • 我把自己标榜为与线程无关的人:到目前为止,我看到的所有示例片段都通过使用 watcher.take() 来阻塞等待线程。他们为什么这么做?预计至少会有一些人使用 watcher.poll() 并睡一会儿。
  • SwingWorker 发布方法似乎不太适合:现在还好,因为我只观看一个目录(不想在错误的方向上走得太远:)当尝试观看多个目录时(如原始 WatchDir 示例)有多个键,并且 WatchEvent 与其中之一相关。要解析路径,我需要事件和目录[A] 关键是看——但只能传一个。不过,很可能逻辑分布是错误的

[A] Edited(由 @trashgods 的评论触发) - 它实际上不是我必须随事件一起传递的密钥,它是报告更改的目录。相应地改变了问题

仅供参考,这个问题被交叉发布到

Addendum

阅读WatchKey的api文档:

有多个线程从手表检索有信号的键 服务然后应注意确保重置方法是 仅在处理对象的事件后调用。

似乎暗示事件应该

  1. 在检索 WatchKey 的同一线程上进行处理
  2. 钥匙重置后不应触摸

不完全确定,但结合(未来)递归观看目录(多个)的要求,决定遵循 @Eels 的建议,有点 - 很快就会发布我决定的代码

EDIT刚刚接受了我自己的答案 - 如果有人有合理的反对意见,我会谦虚地回复这一点


因为你的后台线程完全用于观看,take() http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html#take%28%29是正确的选择。它有效地隐藏了平台依赖 http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html实现,可以转发或轮询。中的一个poll() http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html#poll%28%29例如,如果您的后台线程还需要检查与该队列串联的其他队列,则方法将是合适的WatchService.

附录:因为WatchKey http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchKey.html有状态,它可能不应该被转发到process(). The context() http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchEvent.html#context%28%29 of a WatchEvent http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchEvent.html is a "relative http://download.oracle.com/javase/7/docs/api/java/nio/file/Path.html#relativize%28java.nio.file.Path%29注册到监视服务的目录与创建、删除或修改的条目之间的路径。”其中之一resolve() http://download.oracle.com/javase/7/docs/api/java/nio/file/Path.html#resolve%28java.nio.file.Path%29如果目录共享公共根,方法应该有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WatchService 和 SwingWorker:如何正确执行? 的相关文章

  • 是否可以在 Spring Batch 中结合分区和并行步骤?

    我只是想知道它在 Spring Batch 中可行吗 Step1Step2 流程 gt 流程1 流程2 流程3 Step3 其中每个flow1 gt 划分为 5 个 GridSizeflow2 gt 划分为 5 个 GridSizeflow
  • Spring控制器是线程安全的吗

    我遇到了这个控制器示例 想知道它是否是线程安全的 我特别想知道 gson 实例变量 import org springframework stereotype Controller import org springframework we
  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • 如何在 Eclipse 中用阿拉伯语读写

    我在 eclipse 中编写了这段代码来获取一些阿拉伯语单词 然后打印它们 public class getString public static void main String args throws Exception PrintS
  • 如何从另一个xml文件动态更新xml文件?

    我想从另一个 xml 文件更新 xml 文件 我使用了一个 xml 文件 如下所示 one xml
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 通过 InjectMocks Spy 注入对象

    我需要对一个类运行一系列单元测试 该类具有 Autowired Logger 实现 实现的基本思想是 Mock Logger logger InjectMocks TestedClass tested 但我想保存日志输出功能 Mockito
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • Java 重写 hashCode() 得到 StackOverflowError

    所以我不太熟悉重写 hashCode 并且我似乎在 hashCode 方法中以某种方式进行了一些无限递归 这是我的场景 我有一个 DuplicateCache 类 它是一个缓存对象 用于检查系统中的重复对象 我有一个静态内部类 Duplic
  • 如何将 XMP XML 块序列化为现有的 JPEG 图像?

    我有许多 JPEG 图像 其中包含损坏的 XMP XML 块 我可以轻松修复这些块 但我不确定如何将 固定 数据写回图像文件 我目前正在使用 JAVA 但我愿意接受任何能让这项任务变得容易的事情 这是目标关于 XMP XML 的另一个问题
  • 尝试在没有 GatewayIntent 的情况下访问消息内容

    我希望每当我写一条打招呼的消息时 机器人都会在控制台中响应一条消息 但它只是给我一个错误 JDA MainWS ReadThread WARN JDA Attempting to access message content without
  • tomcat 过滤所有 web 应用程序

    问题 我想对所有网络应用程序进行过滤 我创建了一个过滤器来监视对 apache tomcat 服务器的请求 举例来说 它称为 MyFilter 我在 netbeans 中创建了它 它创建了 2 个独立的目录 webpages contain
  • jmap - 组织和堆操作会给 jvm 带来开销吗?

    正如标题所述 需要多少开销jmap histo and jmap heap分别带到jvm 如果一个内存敏感的 Java 进程处于OutOfMemory 例如 大约 96 的堆已满 并且无法通过 full gc 清除 其中一项操作是否有可能将
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 如何使用 Mockito 和 Junit 模拟 ZonedDateTime

    我需要模拟一个ZonedDateTime ofInstant 方法 我知道SO中有很多建议 但对于我的具体问题 到目前为止我还没有找到任何简单的解决办法 这是我的代码 public ZonedDateTime myMethodToTest
  • Spock模拟inputStream导致无限循环

    我有一个代码 gridFSFile inputStream bytes 当我尝试这样测试时 given def inputStream Mock InputStream def gridFSDBFile Mock GridFSDBFile
  • Java中获取集合的幂集

    的幂集为 1 2 3 is 2 3 2 3 1 2 1 3 1 2 3 1 假设我有一个Set在爪哇中 Set
  • Spring Boot MSSQL Kerberos 身份验证

    目前在我的春季靴子中application properties文件中 我指定以下行来连接到 MSSql 服务器 spring datasource url jdbc sqlserver localhost databaseName spr

随机推荐

  • 为什么我在此语音识别代码中缺少 an4-1-1.match 文件?

    我在语音识别的解码部分遇到问题 我按照步骤操作here http www speech cs cmu edu sphinx tutorial html 当我输入 perl scripts pl decode slave pl 我收到这些错误
  • AWS从EBS切换到EFS

    我正在考虑从 AWS Elastic Block Storage 切换到 AWS Elastic Filesystem 主要是为了易于扩展 而且可共享存储似乎也不错 目前我有一个 debian EC2 实例和一个 EBS 卷 将数据从 EB
  • Python 中丢弃图像时出现内存泄漏

    我目前正在用 Python 编写一个简单的棋盘游戏 我刚刚意识到当图像重新加载时 垃圾收集不会从内存中清除丢弃的位图数据 仅当游戏启动或加载或分辨率更改时才会发生这种情况 但它会增加消耗的内存 所以我不能让这个问题得到解决 重新加载图像时
  • 什么是IDL?

    IDL 是什么意思 我用谷歌搜索了一下 发现它代表接口定义语言 用于组件的接口定义 但是 在实践中 IDL 的目的是什么 微软使用它吗 接口定义语言 IDL 用于在远程过程调用 RPC 中建立客户端和服务器之间的通信 它有很多变体 例如 S
  • batik-rasterizer.jar - 将 svg 转换为 png

    我尝试使用以下命令在我的 Linux 服务器中设置导出服务器 以将图形下载为图像高图表 http www highcharts com docs export module setting up the server command jav
  • 单击p-dialog关闭(X)按钮时如何调用角度函数?

    单击p dialog关闭 X 按钮时如何调用角度函数 我已经搜索并尝试过这个 onHide cancel 但这不起作用 请分享您的解决方案 我知道我们可以使用close cancel按钮隐藏弹出窗口 但在我的场景中 我想在单击 X 按钮单击
  • 在 Swift 中,如何将现有的二进制文件读入数组?

    作为我的项目的一部分 我有一个二进制数据文件 其中包含大量 32 位整数 我的一个类在初始化时读入该文件 在我的 C 库中 我使用以下初始化程序读入它 Evaluator Evaluator m HandNumbers resize 324
  • 如何在向量列表上应用索引向量?

    我想将一个长索引向量 50 多个非连续整数 应用于一长向量列表 包含 100 多个名称的 50 多个字符向量 以便检索特定值 作为列表 向量或数据帧 一个简化的例子如下 gt my list lt list c a b c c d e f
  • 一步一步 YouTrack“在构建中修复”填充 TeamCity 集成

    我正在使用 TeamCity Professional 8 1 和 YouTrack 5 0 6 我已经成功地用两步工作流程填充了 YouTrack 中的 Fixed in build 字段 我在用 issue id 已修复我的 Mercu
  • R闪亮的csv或excel上传选项

    我需要为用户提供上传 csv txt 或 xlsx 格式文件的选项 我正在使用 xlsx 包 并在我的 UI 上提供了一个单选按钮 例如 ui lt dashboardPage dashboardHeader title SKU Healt
  • 如何在pytorch中查看DataLoader中的数据

    我在 Github 上的示例中看到类似以下内容 如何查看该数据的类型 形状和其他属性 train data MyDataset int 1e3 length 50 train iterator DataLoader train data b
  • 获取脚本路径

    在 CSS 中 任何图像路径都是相对于 CSS 文件位置的 f ex 如果我将 CSS 文件放入 media css mystyles css并使用类似的东西 background url images myimage jpg 浏览器将在以
  • NLTK CoreNLPDependencyParser:无法建立连接

    我正在尝试通过 NLTK 使用斯坦福解析器 按照示例here http www nltk org api nltk parse html nltk parse corenlp CoreNLPDependencyParser 20tutori
  • apache 的子进程返回退出代码 -6,但没有 stdout 或 stderr

    当从 apache 进程运行 git status 甚至 ls 时 我经常得不到标准输出或错误 并且退出状态代码为 6 其他时候 它就有效 有什么想法为什么会发生这种情况或者这意味着什么吗 如果您所在的网络有很多人 则可能会耗尽可用的并发连
  • ASP.Net 动态切换母版页

    以前从未需要这样做 但是是否可以动态设置 更改页面正在使用的母版页 有一个旧的 asp net web 表单项目 我为它创建了一个新的引导模板 但老板希望给人们机会打开新的模板 而不是强迫他们使用 我建议您创建一个 BasePage 类 而
  • Java 中的全局异常处理程序

    我正在考虑使用以下命令为我的 Android 移动应用程序 使用 Java 语法 设置一个全局默认异常处理程序Thread setDefaultUncaughtExceptionHandler 称呼 我正在考虑只向用户显示一个带有适当消息的
  • 更改值 recyclerview.adapter 并将其保存到 mainactivity 中的 textview 中?

    当我更改 recyclerview adapter 的值时 我想将其值设置为 mainactivity 中的 textview 该怎么做 it will be like this 从我的 json 中检索回收数据 因此它将是随机的且数据很多
  • Flutter:如何导入现有的 Flutter 项目作为 gradle 项目

    如何导入现有的 Flutter 项目作为 gradle 项目 导入项目 向导要求 Gradle 主路径 我的系统中安装了 gradle 但这里需要设置什么 哪个路径 这是我正在尝试的 Error 我也遇到过这个问题 我必须在 Android
  • 使用 scikit-learn OneClassSVM 时获取每个新观察结果为异常值的概率

    我是 scikit learn 和 SVM 方法的新手 我的数据集与 scikit learn OneClassSVM 配合良好 可以检测异常值 我使用观察来训练 OneClassSVM 所有这些都是 内点 然后使用 Predict 对我的
  • WatchService 和 SwingWorker:如何正确执行?

    WatchService 听起来像是一个令人兴奋的想法 不幸的是 它似乎像教程 api 中警告的那样低级 而且并不真正适合 Swing 事件模型 或者我错过了一些明显的东西 非零概率 获取代码来自教程中的 WatchDir 示例 http