Java流中的flush()方法有什么作用?

155

在Java中,flush()方法用于流。但我不明白使用这个方法的全部目的是什么?

fin.flush();
告诉我一些建议。
7个回答

128

flush方法的文档中可以了解到:

刷新输出流并强制写出任何缓冲的输出字节。 flush方法的通用契约是,如果输出流的实现已经缓冲了以前写入的任何字节,则调用它是一个指示,这些字节应立即被写入其预定目的地。

主要进行缓冲是为了提高I/O性能。更多信息可以从这篇文章中阅读:优化Java I/O性能


1
Java I/O 性能调优的最新链接:http://www.oracle.com/technetwork/articles/javase/perftuning-137844.html - Oleksandr
+1 谢谢。我一直想不通为什么我的字节没有发送出去,原来是因为我需要刷新缓冲区。 - rayryeng
3
flush方法只用于缓冲流吗? 将其与其他流(例如OutputStream)一起使用是否有任何优势? - tnishada
2
也许“flush”这个词不应该出现在它的定义中。递归定义对于理解新事物来说是一个坏主意。我知道你没有写这个定义。 - Jonathan Komar

38
当你向流中写入数据时,它不会立即被写入,而是被缓存。因此,在需要确保所有缓存数据都被写入时使用flush()
在关闭流之前,我们需要确保所有的写入操作都已经完成,这就是为什么在文件/缓冲区写入器的close()中调用flush()的原因。
但是,如果您有一个要求,在关闭流之前任何时候都要保存所有的写入操作,请使用flush()

10
在关闭之前调用 flush 是多余的,对吗?这与简单地调用 close 是一样的。 - John Henckel
2
@BimanTripathy 我可以百分之百地保证。这是由FilterOutputStreamFilterWriter的Javadoc所保证的。 - user207421

31

当我们输入任何命令时,计算机会将该命令的流存储在内存中称为缓冲区(一个临时的内存位置)。当所有临时内存位置都已满时,我们使用flush()函数,它会刷新所有数据流并完全执行它们,并在缓冲区临时位置中为新流提供新的空间。 -希望您能理解


1
只有在BufferedOutputStreamBufferedWriterObjectOutputStreamPrintXXX类的情况下,任何其他流或Writerflush()方法都不起作用。 - user207421
@EJP 有没有任何参考资料来支持你的说法?对于我们这些新手来说会很有帮助 :) - mr5
1
@mr5 需要支持他的陈述的是发帖人,而不是我,但我所说的一切都在Javadoc中清楚地说明了。 - user207421
1
对于 BufferedWriter,不需要显式调用 flush(),只要你调用 close() 关闭写入器即可。close() 会自动执行 flush 操作。 - Yossarian42
注意close()会调用flush(),因此在使用没有缓冲区的FileWriter时,调用两者是多余的。 - Yossarian42

8

如果缓冲区已满,则将缓冲区中的所有字符串保存到磁盘上。缓冲区用于避免大交易和开销。

在java libs中的BufferedWriter类中,有一行代码:

private static int defaultCharBufferSize = 8192;

如果你希望在缓冲区满之前发送数据,你是有控制权的。只需刷新它。调用writer.flush()会说:“现在发送缓冲区中的所有内容!”
参考书籍:https://www.amazon.com/Head-First-Java-Kathy-Sierra/dp/0596009208 页码:453

7
除了其他好的答案之外,这个解释对我来说非常清晰:
缓冲区是内存中用于存储数据流(字符)的一部分。有时,这些字符只会在缓冲区已满或达到某个特定字符数时才会发送到输出设备(例如监视器)。如果您只需要向输出设备发送少量字符,则可能导致系统延迟。 flush() 方法将立即将缓冲区内容刷新到输出流中。
来源:https://www.youtube.com/watch?v=MjK3dZTc0Lg

4

流通常由周期性地清空其内容并将其显示在屏幕上、发送到套接字或写入文件的线程访问。这是出于性能原因。刷新输出流意味着您想停止,等待流的内容完全传输到其目标,然后使用空流和已发送的内容恢复执行。


5
这是幻想。流并不是由任何魔法线程访问的,只有应用程序创建的线程可以访问。 - user207421

3

针对性能问题,首先要将数据写入缓冲区。当缓冲区满时,数据将被写入输出(文件、控制台等)。当缓冲区部分填充而您想将其发送到输出(文件、控制台)时,则需要手动调用flush()方法,以便将部分填充的缓冲区写入输出(文件、控制台)。


这是不正确的。FileOutputStream.flush() 是一个空的无操作。 - vertuso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接