java - 在Java中使用文件锁复制文件

标签 java file-copying file-locking

我正在开发一个 Java 进程,该进程应该有效(并递归地)将文件/目录从源位置复制到目标位置。

为此,我想要:

  • 创建锁
  • 如果目标文件不存在,则复制它
  • 如果目标文件不同,则复制它
  • 否则它们是相同的,所以什么也不做
  • 释放锁

为了检查内容是否相等,我计划使用 Apache Commons IO FileUtils方法contentsEqual(...)。为了进行复制,我计划使用 Apache Commons IO FileUtils方法copyFile(...)

所以,我想出的代码是(这仅适用于文件,目录递归地处理到文件的此方法):

private static void checkAndUpdateFile(File src, File dest) throws IOException {
  FileOutputStream out = new FileOutputStream(dest);
  FileChannel channel = out.getChannel();
  FileLock lock = channel.lock();

  if (!dest.exists()) {
    FileUtils.copyFile(src, out);
  } else if (!FileUtils.contentEquals(src, dest)) {
    FileUtils.copyFile(src, out);
  } 

  lock.release();
  channel.close();
  out.close();
}

这会执行文件锁定(很棒),并复制文件( super )。

但是,每当复制文件时,它都会将复制文件的上次修改时间戳设置为复制时间。这意味着后续调用 FileUtils.contentEquals(src, dest)继续返回false,因此文件被重新复制。

我真正想要的类似于 FileUtils.copyFile(src, dest, true) ,它保留文件时间戳 - 并且通过调用 FileUtils.contentEquals(src, dest) 得到 true。这需要将锁锁定在 File 上,而不是 FileOutputStream 上,否则会调用 FileUtils.copyFile(src, dest, true) 由于文件被锁定而失败并引发异常。

或者,我考虑执行 FileUtils.copyFile(src, dest, true) 方法的操作,即调用 dest.setLastModified(src.lastModified())。但是,这必须在锁释放后调用,如果同一个进程同时执行多次,这可能会导致问题。

我也考虑过将锁放在源文件上,但这并没有帮助,因为我必须将它放在 FileInputStream 上,并且我想传递一个 文件FileUtils.copyFile(src, dest)

所以:

  1. 有没有更简单的方法来实现我想要做的事情?
  2. 是否可以对文件而不是文件的派生对象加锁?
  3. 解决这个问题的最佳方法是什么?
    • 即我只需要为此编写自己的方法吗? (可能是copyFile(...))

最佳答案

您可以使用Guava Google Core Library来比较两个文件。

As Byte Source

ByteSource Doc

        ByteSource inByte = Resources.asByteSource(srcFileURL);
        ByteSource outByte = Files.asByteSource(srcFileURL2);
        boolean fileEquals= inByte.contentEquals(outByte));

关于java - 在Java中使用文件锁复制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20471374/

相关文章:

java - 为什么Java中数组的每个元素都会不断变化?

shell - 在 Linux (CygWin) shell 脚本中锁定文件(并检测该锁定)

c - 在 Linux 中使用重命名来安全地覆盖共享文件

java - JPA ,多对多关系,删除所有以前的关系并进入新关系

java - JAVA 和 MYSQL 中的 WEEK_OF_YEAR 错误

java - setMultiChoiceItems 的光标未填充列表

inno-setup - Inno Setup - FileCopy 在路径名中使用通配符

c++ - 使用 Windows CopyFile 函数复制具有特定名称格式的所有文件

c# - 从 File.Copy 中排除系统硬链接(hard link)

C++:线程和进程之间的文件锁