尽管进行了检查,但有时还是会覆盖文件

时间:2019-04-10 11:55:26

标签: java file nio

我有一个可以处理某些文件的代码:

Path path = ...;
if (!path.toFile().exists() || Files.size(path) == 0L) {
  Files.write(path, data, StandardOpenOption.CREATE);
}

它几乎总是可以正常工作,但是在某些情况下,它会覆盖现有文件,因此我的文件被损坏,旧数据被新数据覆盖。例如,如果在上面的代码中文件内容为00000000000000,而dataAAA,我将获得内容为AAA00000000000的文件。 文件访问已很好地同步,因此只有一个线程可以访问文件,只能同时启动一个应用程序实例。应用程序正在Heroku(它是由Heroku管理的文件系统)上运行,我无法在笔记本电脑上重现相同的行为。

Files.size(path)对于包含某些数据的文件是否会返回零?如何重写此代码以使其正常工作?如果文件不为空或不存在,是否可以使用另一个StandardOpenOption标志失败(引发异常)?

2 个答案:

答案 0 :(得分:0)

具有数据的现有文件的预期行为是什么?

  1. 丢弃现有数据

    您可以一起使用CREATE和TRUNCATE_EXISTING。实际上,也许您不应该使用任何内容,因为write()的默认值为每个the documentation的CREATE,TRUNCATE_EXISTING,WRITE。

  2. 保留现有数据

    您可以在APPEND模式而不是WRITE模式下打开它。

  3. 如果文件已经存在并且不为空,则不执行任何操作。

    这很棘手。非零尺寸的报告令人担忧。我建议使用CREATE_NEW(如果存在,则失败),如果您遇到失败异常,请读取文件以查看其是否为非空。

答案 1 :(得分:0)

您的代码包含种族危险,因为它执行了不能依靠的“跳前先看”。在您的谓词之间

<div class="flex-box">
  <span>Adress: </span>
  <div>customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer customer </div>
</div>

赋予!path.toFile().exists() || Files.size(path) == 0L (您认为)意味着文件没有以前的内容,然后执行true写入文件,这是一个不同的进程(或线程)可能已写入文件。