Java原子文件因断电而移动重复文件

时间:2019-11-06 18:19:55

标签: java linux debian filesystems ext4

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 个答案:

答案 0 :(得分:2)

我认为您误会了原子动作:

  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中断,您将只有一个文件,但是,如果电源中断,则不再保证文件系统在恢复时的状态。

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