Java 断电时原子文件移动复制文件

Java atomic file move duplicates files on power loss

Java 应用程序按以下方式移动原子文件:

Path source = Paths.get(fullFileName + ".tmp");
Path target = Paths.get(fullFileName);

Files.delete(target);
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);

源文件存在或在移动前被创建。 源和目标位于同一位置,因此具有相同的 FileSystemProvider。 使用原子移动选项,我希望在任何给定时刻系统中只存在一个文件或抛出异常。

然而,当发生断电时,我发现驱动器上的源文件和目标文件具有相同的内容。 我不排除其他潜在问题,但到目前为止它一直可靠地留下重复项。

File system: EXT4
Storage type: eMMC Flash
CPU Architecture: ARM
OS: Debian 4.9.11-02300-ga1ac172-dirty #2 SMP PREEMPT Mon Apr 23 12:58:56 CDT 2018 armv7l GNU/Linux

我错过了什么吗? 这是否意味着不支持原子移动?

我认为您误解了什么是原子移动:

  1. 只有移动是原子的。其余的文件处理不是。
  2. POSIX 原子性保证是针对正常运行的软件,而不是断电情况。

考虑您的代码:

void foo(String fullFileName) {
    // 1
    Path source = Paths.get(fullFileName + ".tmp");
    // 2
    Path target = Paths.get(fullFileName);
    // 3
    Files.delete(target);
    // 4
    Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
    // 5
}

如果程序在 1、2 或 3 处中断,那么您将这两个文件都留在系统中。你的原子移动还没有被调用,所以在那里移动不会影响任何东西。

如果程序在 4 或 5 时中断,您将只有一个文件,但如果电源中断,则文件系统恢复时的状态将不再有任何保证。

听起来你想要的是一个支持事务的数据库。