StandardOpenOption.WRITE + StandardOpenOption.CREATE withwithout TRUNCATE_EXISTING之间的区别?

问题描述 投票:0回答:1

可能是个简单的答案,但我试着阅读了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时,我从来没有得到这种竞赛条件。几乎就像它会先锁定文件一样?谁能解释一下背后发生了什么?

java file nio java-io
1个回答
0
投票

的时候会发生什么?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
$
© www.soinside.com 2019 - 2024. All rights reserved.