可能是个简单的答案,但我试着阅读了StandardOpenOption的javadoc文档,但我仍然不清楚当我说 "TRUNCATE_EXISTING "时会发生什么。
Files.write(..., ..., StandardOpenOption.WRITE, StandardOpenOption.CREATE); // Write A
根据本地的一些测试,如果文件已经存在的话,这样做似乎还是会覆盖文件,那么上面和
Files.write(..., ..., StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); // Write B
?
此外,我有一个有两个线程的程序,从写好的文件中读写。当我使用Write B时,有时会出现一个竞赛条件,即一个线程创建了文件,而另一个线程在第一个线程读取时覆盖了文件,我得到一个异常。但是当我使用写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
$