4

查看PrintWriter以下构造函数的合同时:

public PrintWriter(OutputStream out, boolean autoFlush)

PrintWriter从现有的OutputStream. 这个便利的构造函数创建了必要的中间层OutputStreamWriter,它将使用默认字符编码将字符转换为字节。

参数:
out- 一个输出流
autoFlush- A boolean; if true, println, printf, orformat方法将刷新输出缓冲区

另请参阅:OutputStreamWriter.OutputStreamWriter(java.io.OutputStream)

请注意,该autoFlush标志仅适用于printlnprintfformat。现在,我知道这一点,printf并且format基本上做与除了更多选项完全相同的事情print,但我只是不明白为什么它们没有包含print在合同中。他们为什么做出这个决定?

4

1 回答 1

3

我怀疑这是因为 Java 作者对性能做出了假设:

考虑以下代码:

public static void printArray(int[] array, PrintWriter writer) {
    for(int i = 0; i < array.length; i++) {
        writer.print(array[i]);
        if(i != array.length - 1) writer.print(',');
    }
}

您几乎肯定不希望flush()在每次调用后调用这种方法。这可能会对性能造成很大影响,尤其是对于大型阵列。而且,如果出于某种原因你确实想要这样,你可以打电话给 flush 你自己

这个想法是printf,formatprintln方法可能会同时打印一大块文本,因此在每个之后都刷新是有意义的。但是,如果有的话,它很少会在仅仅 1 个或几个字符之后有意义。


经过一番搜索,我找到了这个推理的引文(强调我的):

到目前为止,我们看到的大多数示例都使用无缓冲 I/O。这意味着每个读取或写入请求都由底层操作系统直接处理。这会使程序的效率大大降低,因为每个这样的请求通常都会触发磁盘访问、网络活动或其他一些相对昂贵的操作。

为了减少这种开销,Java 平台实现了缓冲 I/O 流。缓冲输入流从称为缓冲区的内存区域读取数据;仅当缓冲区为空时才调用本机输入 API。类似地,缓冲输出流将数据写入缓冲区,并且仅当缓冲区已满时才调用本机输出 API。

<剪辑>

在关键点写出缓冲区通常是有意义的,而不是等待它填满。这称为刷新缓冲区。

一些缓冲输出类支持自动刷新,由可选的构造函数参数指定。启用自动刷新时,某些关键事件会导致刷新缓冲区。例如,自动PrintWriter刷新对象在每次调用printlnor时刷新缓冲区format

于 2015-04-20T18:11:56.113 回答