我们的门户网站将读取json文件以显示信息。 json文件将由java编写的作业生成。
我担心如果java进程直接写json,网站进程可能会得到一个不完整的文件,因为java进程正在写文件。
所以我决定将信息写入临时文件,在临时文件正常后,重命名为目标文件,这样网站进程就会得到完整的json文件。
但我仍然担心在重命名文件时,任何进程都可以读取目标文件的中间状态。实际上,我不知道java如何实现重命名操作。
我的代码如下:
Path source = FileSystems.getDefault().getPath("/data/temp/temp.7z.bak");
Files.move(source, source.resolveSibling("/data/temp/temp.7z"), StandardCopyOption.REPLACE_EXISTING);
答案 0 :(得分:1)
您可能希望在方法调用中使用ATOMIC_MOVE
选项:
Files.move(source, source.resolveSibling("/data/temp/temp.7z"), StandardCopyOption.ATOMIC_MOVE));
确实,documentation表示
ATOMIC_MOVE
此移动以原子文件系统操作和所有其他操作执行 选项被忽略。如果目标文件存在,那么它是 如果替换现有文件或具有此特定实现 方法因抛出IOException而失败。 如果移动不能 作为原子文件系统操作执行然后 抛出 AtomicMoveNotSupportedException 。这可能会出现 例如,当目标位置在不同的FileStore上时 将要求复制文件,或目标位置是 与此对象的不同提供者关联。
这应该保证文件在没有中间状态的情况下完全移动。
请注意,如果无法进行此类原子操作,您将获得AtomicMoveNotSupportedException
。