可能是一个简单的答案,但我已经尝试阅读有关 StandardOpenOption 的 javadoc 文档,但我仍然不清楚当我说时会发生什么
Files.write(..., ..., StandardOpenOption.WRITE, StandardOpenOption.CREATE);//写一个
根据一些本地测试,看起来如果文件已经存在,这仍然会覆盖该文件,那么上面和上面有什么区别
Files.write(..., ..., StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);//写B
?
此外,我有一个带有两个线程的程序,可以从写入的文件中读取/写入。当我使用 Write B 时,我有时会遇到竞争条件,其中一个线程创建了该文件,而另一个线程在第一个线程正在读取时覆盖该文件,并且出现异常。但是当我使用 Write A 时,我永远不会遇到这种竞争条件。几乎就像它会先锁定文件一样?有人可以解释一下幕后发生了什么吗?
最佳答案
当您使用StandardOpenOption.TRUNCATE_EXISTING
时如果文件在任何写入之前已经存在,则文件的长度首先被“截断为0”:
$ jshell
jshell> import java.nio.file.*;
jshell> Path path = Paths.get("foo");
path ==> foo
jshell> Files.write(path, "AAAA".getBytes(), StandardOpenOption.WRITE, StandardOpenOption.CREATE)
我刚刚创建了一个名为“foo”的新文件,其中包含字符串“AAAA”:
$ more foo
AAAA
$
现在我将字符串“BB”写入文件没有 StandardOpenOption.TRUNCATE_EXISTING
选项:
jshell> Files.write(path, "BB".getBytes(), StandardOpenOption.WRITE, StandardOpenOption.CREATE)
只有前两个字符被覆盖,其他字符仍然存在:
$ more foo
BBAA
$
现在我再次写入字符串“BB”,但我添加 StandardOpenOption.TRUNCATE_EXISTING
选项:
jshell> Files.write(path, "BB".getBytes(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
该文件仅包含“BB”,因为在写入之前其先前的内容已被 StandardOpenOption.TRUNCATE_EXISTING
“删除”:
$ more foo
BB
$
关于java - 带/不带 TRUNCATE_EXISTING 的 StandardOpenOption.WRITE + StandardOpenOption.CREATE 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62394352/