【发布时间】:2013-12-26 14:33:35
【问题描述】:
我正在开发一个 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();
}
这会锁定文件(很棒),并复制文件(超级)。
但是,无论何时复制文件,它都会将复制文件的最后修改时间戳设置为复制时间。这意味着对FileUtils.contentEquals(src, dest) 的后续调用会继续返回false,因此会重新复制文件。
我真正想要的是类似于FileUtils.copyFile(src, dest, true),它保留了文件时间戳——并且确实通过调用FileUtils.contentEquals(src, dest) 实现了。这将要求锁定在File,而不是FileOutputStream,否则对FileUtils.copyFile(src, dest, true) 的调用将失败并抛出异常,因为文件已被锁定。
另外,我考虑做FileUtils.copyFile(src, dest, true) 方法所做的事情,即调用dest.setLastModified(src.lastModified())。但是,这必须在锁被释放后调用,如果同一个进程同时执行了多次,这可能会导致问题。
我也考虑过将锁锁定在源文件上的想法,但这无济于事,因为我必须将其锁定在 FileInputStream 上,并且我想将 File 传递给 @987654341 @。
所以:
- 有没有更简单的方法来实现我想要做的事情?
- 是否可以锁定文件而不是文件的派生项?
- 解决此问题的最佳方法是什么?
- 即我只需要为此编写自己的方法吗? (可能是
copyFile(...))
- 即我只需要为此编写自己的方法吗? (可能是
【问题讨论】:
标签: java file-copying file-locking