当我的java进程重命名源文件时,任何进程都可以读取目标文件

时间:2016-01-27 10:12:52

标签: java nio

我们的门户网站将读取json文件以显示信息。 json文件将由java编写的作业生成。

  1. 我担心如果java进程直接写json,网站进程可能会得到一个不完整的文件,因为java进程正在写文件。

  2. 所以我决定将信息写入临时文件,在临时文件正常后,重命名为目标文件,这样网站进程就会得到完整的json文件。

  3. 但我仍然担心在重命名文件时,任何进程都可以读取目标文件的中间状态。实际上,我不知道java如何实现重命名操作。

  4. 我的代码如下:

    Path source = FileSystems.getDefault().getPath("/data/temp/temp.7z.bak");
    Files.move(source, source.resolveSibling("/data/temp/temp.7z"), StandardCopyOption.REPLACE_EXISTING);
    

1 个答案:

答案 0 :(得分:1)

您可能希望在方法调用中使用ATOMIC_MOVE选项:

Files.move(source, source.resolveSibling("/data/temp/temp.7z"), StandardCopyOption.ATOMIC_MOVE));

确实,documentation表示

  

ATOMIC_MOVE

     

此移动以原子文件系统操作和所有其他操作执行   选项被忽略。如果目标文件存在,那么它是   如果替换现有文件或具有此特定实现   方法因抛出IOException而失败。 如果移动不能   作为原子文件系统操作执行然后   抛出 AtomicMoveNotSupportedException 。这可能会出现   例如,当目标位置在不同的FileStore上时   将要求复制文件,或目标位置是   与此对象的不同提供者关联。

这应该保证文件在没有中间状态的情况下完全移动。

请注意,如果无法进行此类原子操作,您将获得AtomicMoveNotSupportedException