Java:观察目录以移动大文件

2023-12-24

我一直在编写一个程序来监视目录,当在其中创建文件时,它会更改名称并将它们移动到新目录。在我的第一个实现中,我使用了 Java 的 Watch Service API,当我测试 1kb 文件时,它运行良好。出现的问题是,实际上创建的文件大小在 50-300mb 之间。当这种情况发生时,观察者 API 会立即找到该文件,但无法移动它,因为它仍在写入中。我尝试将观察者放入循环中(这会生成异常,直到可以移动文件为止),但这似乎效率很低。

由于这不起作用,我尝试使用计时器每 10 秒检查一次文件夹,然后在可能的情况下移动文件。这就是我最终采用的方法。

问题:当文件写入完成时是否有任何信号发出信号而不进行异常检查或不断比较大小?我喜欢对每个文件仅使用一次 Watcher API 的想法,而不是不断地检查计时器(并遇到异常)。

非常感谢所有回复!

nt


我今天遇到了同样的问题。在我的用例中,在文件实际导入之前的一个小延迟并不是一个大问题,而且我仍然想使用 NIO2 API。我选择的解决方案是等到文件10秒没有被修改后再对其执行任何操作。

实现的重要部分如下。程序将一直等待,直到等待时间到期或发生新事件。每次修改文件时都会重置过期时间。如果在等待时间到期之前删除文件,则会将其从列表中删除。我使用 poll 方法,超时时间为预期的过期时间,即 (lastmodified+waitTime)-currentTime

private final Map<Path, Long> expirationTimes = newHashMap();
private Long newFileWait = 10000L;

public void run() {
    for(;;) {
        //Retrieves and removes next watch key, waiting if none are present.
        WatchKey k = watchService.take();

        for(;;) {
            long currentTime = new DateTime().getMillis();

            if(k!=null)
                handleWatchEvents(k);

            handleExpiredWaitTimes(currentTime);

            // If there are no files left stop polling and block on .take()
            if(expirationTimes.isEmpty())
                break;

            long minExpiration = min(expirationTimes.values());
            long timeout = minExpiration-currentTime;
            logger.debug("timeout: "+timeout);
            k = watchService.poll(timeout, TimeUnit.MILLISECONDS);
        }
    }
}

private void handleExpiredWaitTimes(Long currentTime) {
    // Start import for files for which the expirationtime has passed
    for(Entry<Path, Long> entry : expirationTimes.entrySet()) {
        if(entry.getValue()<=currentTime) {
            logger.debug("expired "+entry);
            // do something with the file
            expirationTimes.remove(entry.getKey());
        }
    }
}

private void handleWatchEvents(WatchKey k) {
    List<WatchEvent<?>> events = k.pollEvents();
    for (WatchEvent<?> event : events) {
        handleWatchEvent(event, keys.get(k));
    }
    // reset watch key to allow the key to be reported again by the watch service
    k.reset();
}

private void handleWatchEvent(WatchEvent<?> event, Path dir) throws IOException {
    Kind<?> kind = event.kind();

    WatchEvent<Path> ev = cast(event);
        Path name = ev.context();
        Path child = dir.resolve(name);

    if (kind == ENTRY_MODIFY || kind == ENTRY_CREATE) {
        // Update modified time
        FileTime lastModified = Attributes.readBasicFileAttributes(child, NOFOLLOW_LINKS).lastModifiedTime();
        expirationTimes.put(name, lastModified.toMillis()+newFileWait);
    }

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

Java:观察目录以移动大文件 的相关文章

随机推荐

  • 获取 iOS Swift 中的顶级 ViewController

    我想实现一个单独的 ErrorHandler 类 它显示某些事件的错误消息 此类的行为应该从不同的其他类中调用 当发生错误时 会有一个UIAlertView作为输出 此 AlertView 的显示应始终位于顶部 因此 无论错误从哪里抛出 最
  • 如何将 RPC 与 Volttron 结合使用

    我想在我的 volttron 应用程序中使用 RPC 调用 但我无法让任何调用正常工作 所有调用都会失败 并出现 没有到主机的路由 错误
  • 为什么 Django 开发服务器会挂在这个管理工具 JS 文件上?

    使用 Django 管理工具时 它会定期挂起并停止响应请求 直到重新启动为止 每当它挂起时 日志中的最后一行是 获取 admin jsi18n HTTP 1 1 200 2158 挂起似乎发生在 POST 之后 例如查看添加对象的结果时 据
  • flowtype如何用可选字段注释联合

    如何在流程中实现以下目标 export type Response err string data Array data Array 我想表达一种类型 它返回错误和可选数据 或者不返回错误字段 如果没有 但是 我用它作为 return er
  • “npx tsc --version”报告虚拟机内不同的 TypeScript 版本

    我希望能够跑步npx tsc在我的主机 来宾操作系统上的项目中 但客人正在使用不同的 旧的 版本tsc 我不确定它是从哪里来的 我的设置 主机操作系统 Windows 10 来宾操作系统 Debian 9 我正在使用 VirtualBox
  • 使用 IDisposable 取消订阅事件

    我有一个处理来自 WinForms 控件的事件的类 根据用户正在执行的操作 我引用该类的一个实例并创建一个新实例来处理同一事件 我需要首先从事件中取消订阅旧实例 很简单 如果可能的话 我想以非专有的方式执行此操作 这似乎是 IDisposa
  • JQuery 自动完成:如何强制从列表中选择(键盘)

    我正在使用 JQuery UI 自动完成 一切都按预期进行 但是当我使用键盘上的向上 向下键循环时 我注意到文本框按预期填充了列表中的项目 但是当我到达列表末尾并再次按下向下箭头时这时 我输入的原始术语就会出现 这基本上允许用户提交该条目
  • git p4克隆/同步:如何添加新的P4路径

    我创建了一个 P4 客户端视图规范 并用它制作了一个 git p4 克隆 并定期同步 P4 的更改 效果非常好 有一天 我想向我克隆的 Git 存储库添加另一个 P4 路径 但它卡住了 即使我添加了 git p4 克隆使用的客户端视图规范的
  • mysql 自动终止查询

    mysql 是否有可能自动终止耗时超过 20 秒的查询 我猜您正在寻找名为 mk kill 的 maatkit 实用程序 它将杀死符合某些条件的查询
  • Tf.Print() 不打印张量的形状?

    我使用 Tensorflow 编写了一个简单的分类程序并获取输出 但我尝试打印模型参数 特征和偏差的张量形状 函数定义 import tensorflow as tf numpy as np from tensorflow examples
  • 我的解决方案中有两个 Web 项目,要部署哪一个

    我有一个像这样结构的解决方案 Proj Soln Proj Api csproj Proj Web csproj 我已使用 bitbucket org 配置了 microsoft azure 当我通过 git 提交到 bitbucket 时
  • Linux Mint 19.2 上的 Docker 安装不起作用 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 刚刚安装了一个新的 Linux mint 19 2 我需要 docker 所以我去了 docker 文档并遵循了该过程 https doc
  • 将值传递给捆绑的 React JS 文件?

    我想知道是否可以将参数传递给反应入口点 我的入口点如下所示 module exports entry js components Application js output path dist filename bundle js 我的应用
  • 如何在turbo c++ 16位编译器中创建项目

    我想创建一个项目文件 Turbo C 并链接该项目中的文件 虽然我已经尝试过 但我发现只有一个选项可以打开项目 没有选项可以创建新项目 那么如何做到这一点 基本上 你想做的是 开放项目 在那里 您输入项目名称 它必须以 PRJ 当你open
  • Angular2 中的事件委托

    我正在 ng2 中开发一个应用程序 但我正在努力解决一些问题 我正在构建一个日历 您可以在其中选择日期范围 我需要对此做出反应click mouseenter mouseleave日细胞上的事件 所以我有一个像这样的代码 简化的 日历 组件
  • 如何更改 SonataAdmin 中的“奏鸣曲项目”链接?

    我的 SonataAdminBundle 有问题 我找不到如何更改左侧板上的 奏鸣曲项目 链接 我有 我的标题 一张图片 下面有 奏鸣曲项目 我怎样才能改变这个 In order to customize the content of th
  • crypto.pbkdf2 导出 IV 和密钥到 crypto.createCipheriv 的正确设置是什么?

    在 Node js 的应用程序中 我使用加密模块 https nodejs org api crypto html用于对称加密 解密 我正在使用 AES 256 CTR 我最初假设加密 createCipher https nodejs o
  • 应用程序 onCreate 在 Activity onCreate 之后调用(未调用)

    在崩溃日志中 我发现了非常奇怪的应用程序错误 该错误发生在 Android 7 0 8 0 上 对于一些少量用户来说 但非常频繁 我无法重现该问题 这里的代码反映了当前应用程序的状态 我有一个对我的应用程序类的静态引用 public cla
  • 防止delayed_job后台作业在单个服务器上消耗过多的CPU

    我的 Rails 应用程序有许多任务被卸载到后台进程中 例如调整图像大小和上传到 S3 我在用着延迟作业 http github com collectiveidea delayed job tree master来管理这些流程 这些过程
  • Java:观察目录以移动大文件

    我一直在编写一个程序来监视目录 当在其中创建文件时 它会更改名称并将它们移动到新目录 在我的第一个实现中 我使用了 Java 的 Watch Service API 当我测试 1kb 文件时 它运行良好 出现的问题是 实际上创建的文件大小在