Java:确保 Files.list() 仅返回 "complete"文件

标签 java filesystems nio

在我的应用程序中,我监视新文件的目录。

我保留了通过Files.list(dir)获得的当前文件的数组。 ,一个接一个地处理此列表文件,然后使用 Files.list() 重新加载目录。再次。

虽然我自己从未遇到过这个问题,但一位同事告诉我,前任软件有一个额外的检查,检查文件是否早于 3 秒(用 (Files.getLastModifiedTime(path) - System.currentTimeMillis()) > 3000 计算),因为存在传输不完整的问题(或者更好:尚未完全传输)文件已进入处理。

我可以假设 Files.list() 返回的文件吗?已完全复制到我正在观看的目录中?

是否有更简洁的方法来检查文件是否完整? 3 秒检查更像是一种 hack,可以通过慢速连接(网络)复制多个 GB 大小的文件,并且即使经过 3 秒也可能无法完全传输。

最佳答案

如果文件位于目录中,则认为文件完整是不安全的。仍然可能存在与另一个进程关联的锁,该进程可能正在写入该锁或出于不同的原因持有该锁。

我使用以下方法来检查文件是否准备好(这使用java 1.8)

public static boolean isFileReady(Path file) {
  try(FileChannel ch = FileChannel.open(file, StandardOpenOption.WRITE, StandardOpenOption.APPEND); FileLock lock = ch.tryLock()) {
    if (lock == null) return false;
    return true;
  } catch (IOException ex) {
    return false;
  }
}

这将尝试打开文件进行追加(打开正常写入将删除其所有内容)并创建锁。如果锁定已建立,那么我们就可以开始,否则就不会。

关于Java:确保 Files.list() 仅返回 "complete"文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53415392/

相关文章:

java - @RecentlyNonNull 注释是什么?

java - 在什么情况下静态方法是一个好习惯?

java - 合并 2 个具有相同元素的 XML 文件并将 id 分配给唯一的项目

java - 重用套接字 channel

java - 在 android 的应用程序之间导航

xcode - 我应该如何组织我的Xcode项目文件?

perl - Cwd::abs_path() 返回 undef

filesystems - EXT4 中每个目录的最大文件数是多少?

nio - 使用Java 7新IO获取文件/目录大小

Java 1.7ea : Files. probeContentType(path) 返回 null