FileOutputStream 是否截断现有文件

Does FileOutputStream truncate an existing file

提问人:Raedwald 提问时间:3/13/2013 最后编辑:Raedwald 更新时间:7/14/2017 访问量:9369

问:

确实如此

 final OutputStream output = new FileOutputStream(file);

如果已经存在,请截断?令人惊讶的是,Java 6 的 API 文档没有说。Java 7 的 API 文档也没有。语言本身的规范与类的语义无关。fileFileOutputStream

我知道

 final OutputStream output = new FileOutputStream(file, true);

导致追加到文件。但追加和截断并不是唯一的可能性。如果将 100 个字节写入 1000 字节的文件中,一种可能性是最后的 900 个字节保持原样。

Java 文件

评论

0赞 Raedwald 3/13/2013
参见:stackoverflow.com/q/14280385/545127
0赞 Raedwald 3/13/2013
参见:stackoverflow.com/q/2622206/545127

答:

-3赞 Bastien Jansen 3/13/2013 #1

FileOutputStream用于写入二进制数据,这些数据最常被覆盖。

如果您正在操作文本数据,则最好使用具有方便方法的 FileWriterappend

3赞 JFK 3/19/2013 #2

我在 Windows 2008 x86 和 java 1.6.0_32-b05 上尝试过这个

我创建了 2 个进程,它们不断写入同一个文件,一个 1Mb 的字符“b”,另一个 4Mb 的字符“a”。除非我用

out = new RandomAccessFile(which, "rw");
out.setLength(0);
out.getChannel().lock();

我发现第三个读取器进程可以读取一个文件,该文件以 1Mb 的“b”开头,然后是“a”

我发现先写到一个临时文件,然后重命名它

File.renameTo

到文件也有效。

我不会依赖 Windows 上的 FileOuputStream 来截断可能正在被第二个进程读取的文件......

  • 不是新的 FileOutputStream(file)
  • 也不是 FileOutputStream(file, false) ( 不截断 )
  • 也不

这;

out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);

然而

out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);
out.getChannel().lock();

确实有效

评论

0赞 Raedwald 3/19/2013
“我不会依赖 Windows 上的 FileOuputStream 来截断可能正在被第二个进程读取的文件” 您可能需要检查代码中的争用条件。第二个进程是否在第一个进程对文件进行 -ed 之前读取文件?close()
0赞 JFK 3/20/2013
我希望如此,这就是重点。我试图确保 2 个写入器进程使文件处于一致状态,并且读取器进程无法读取半写入的文件。如果可以上传代码,我可以分享代码。好的,所以你只问截断,但我的重点是看看什么给出了一致的读数......
10赞 ths 7/14/2017 #3

FileOutputStream如果没有该选项,则截断文件。append

请注意,打开的是 Stream,而不是随机访问文件,所以我想它以这种方式运行确实有意义,尽管我同意文档可以更明确地说明它。FileOutputStream

评论

0赞 Johannes Bittner 11/11/2017
你有这方面的来源吗?
0赞 ths 11/11/2017
@JohannesBittner为了什么?它是一条溪流?它就在名字里。此外,该类不提供任何截断或移动 FP 的方法,如果它不会在打开时截断,则该类将毫无用处。
2赞 Johannes Bittner 11/14/2017
我的意思是 FileOutputStream 在没有 append 选项的情况下截断文件的语句的来源。我对 Java 中 Stream 的语义不太有信心,在我的理解中,它也可能是它写入文件,而文件末尾保持不变。例如,您将 200 个字节写入一个长度为 800 字节的现有文件,导致尾随的 600 个字节未被修改。我不明白为什么这本身没有意义。
0赞 ths 11/14/2017
@JohannesBittner您可以自己轻松尝试。