PrintWriter是否具有缓冲功能?

9
我知道如果我们想要写格式化数据,PrintWriter非常好用,我也知道使用BufferedWriter可以提高IO性能。

但是我尝试过类似这样的操作:

PrintWriter pw = new PrintWriter(System.out);
pw.println("Statement 1");
pw.println("Statement 2");
//pw.flush();

我注意到当注释掉flush方法时没有输出,但是取消注释后就可以得到期望的输出。只有PrintWriter被缓冲才可能这样。那么,使用BufferedWriter包装PrintWriter并写入它有什么意义呢?虽然javadoc没有在任何地方提到PrintWriter是被缓冲的,但它似乎确实被缓冲了。

所有的编写者都有flush方法。 - nafas
4个回答

9

我检查了从1.6.0_45版本开始的所有JDK版本,它们都有这个构造函数:

/**
 * Creates a new PrintWriter from an existing OutputStream.  This
 * convenience constructor creates the necessary intermediate
 * OutputStreamWriter, which will convert characters into bytes using the
 * default character encoding.
 *
 * @param  out        An output stream
 * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
 *                    <tt>printf</tt>, or <tt>format</tt> methods will
 *                    flush the output buffer
 *
 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
 */
public PrintWriter(OutputStream out, boolean autoFlush) {
this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);

因此,PrintWritter使用缓冲输出。如果您想使用您所指出的代码,您可以创建一个具有自动刷新设置为true的PrintWriter,这将确保使用其中一个printlnprintfformat方法会刷新流。因此,在给定上下文中,您的代码将如下所示:
PrintWriter pw = new PrintWriter(System.out, true);
pw.println("Statement 1");
pw.println("Statement 2");

恩,只是想指出如果在 Java 规范中没有提到 PrintWriter 应该使用缓冲区,那么未来的 Java 版本可能就不会这样了。实现可以改变。我相当确定这被称为抽象或封装 - 不确定是哪一个。 - John Red
@JohnRed 谢谢您的评论,如果您认为回复可以改进,请编辑它。 - Olimpiu POP

8

从Java 8 PrintWriter源代码

/**
 * Creates a new PrintWriter from an existing OutputStream.  This
 * convenience constructor creates the necessary intermediate
 * OutputStreamWriter, which will convert characters into bytes using the
 * default character encoding.
 *
 * @param  out        An output stream
 * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
 *                    <tt>printf</tt>, or <tt>format</tt> methods will
 *                    flush the output buffer
 *
 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
 */
public PrintWriter(OutputStream out, boolean autoFlush) {
    this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);

你可以看到PrintWriter使用了BufferedWriter,并且它有一个选项autoFlush,只有在缓冲时才有意义。

2

PrintWriter是有缓冲区的。不同之处在于,PrintWriter提供了写入格式化对象的便捷方法,如println()printf()。它还具有自动刷新功能(因此显然具有缓冲区)。

这两个类都很高效。如果启用了PrintWriter的自动刷新,则其效率可能会降低(因为每次调用像println()这样的方法后都会进行刷新)。另一个区别是PrintWriter不允许直接写入字节。


PrintWriter也有写入方法。“另一个区别是PrintWriter实际上不允许您直接写入字节”,我不理解这个声明。 - Payal Bansal

0

我认为既然PrintWriter也可以一次读取字符串,那么它应该使用缓冲区。


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