Java中创建硬链接和删除文件的原子操作

Java中创建硬链接和删除文件的原子操作,java,atomic,Java,Atomic,我正在Unix上用JDK 7编写一段代码,比较两个文件。 如果两个文件相同,则表示文件A和文件B 然后它应该删除文件B并创建到文件a的硬链接 简单的方法是: 1. Compare if files are same a. delete File B b. use Path to File B to createLink to File A 但问题是这不是原子的。因此,出于某种原因,如果我的Java代码在步骤1之后死亡。我把文件丢了 一种解决方案是创建备份文件,并在以后进程

我正在Unix上用JDK 7编写一段代码,比较两个文件。 如果两个文件相同,则表示文件A和文件B

然后它应该删除文件B并创建到文件a的硬链接

简单的方法是:

  1. Compare if files are same
    a. delete File B
    b.  use Path to File B to createLink to File A
但问题是这不是原子的。因此,出于某种原因,如果我的Java代码在步骤1之后死亡。我把文件丢了

一种解决方案是创建备份文件,并在以后进程运行正常时清理它

但我正在寻找更优雅的解决方案,我可以把它作为一个原子操作来完成。请帮忙


谢谢

我能想到的最安全的方法是在目标目录中用临时名称创建硬链接,然后作为最后一步,重命名它,从而覆盖目标

您的基本算法将与以下代码片段大致相同:

if (FileContentComparator.same(FileA, FileB)) {
    Files.createLink(TempB, FileA);
    TempB.renameTo(FileB);
}
在同一文件系统中重命名文件通常是原子的,因此相当安全。对临时名称使用已知模式将允许查找和处理它们,即使应用程序在执行最终重命名之前意外终止


至少会很高兴地覆盖目标,而不会有任何麻烦-您必须调查Java NIO类的行为。

我认为您最好在
finally
块中使用一些清理代码。但是,除非您的操作系统支持这种原子操作(我对此表示怀疑),否则就没有办法保护自己免受Java崩溃的影响。毕竟,任何本应执行的Java在崩溃时都不会执行,我真的看不到有机会在这里做任何花哨或优雅的事情。让文件在最后一步删除怎么样?这样,如果Java在此过程中崩溃,您不会丢失任何东西。@安定如果文件
FileA
存在,则无法创建名为
FilaA
的硬链接。@NullUserExceptionఠ_ఠ: 哦,你说得对。我想你必须用一个不同的名称创建它,然后你的最后两个步骤是删除文件,然后重命名链接…但是你如何使这个操作原子化。。。hmm@Shakedown:至少在Linux上,
重命名
系统调用是原子的,即使在覆盖目标时也是如此-不需要特殊的魔法。我不知道在其他系统上会发生什么,尽管我怀疑它会几乎相同。