When looking at the PrintWriter
contract for the following constructor:
public PrintWriter(OutputStream out, boolean autoFlush)
Creates a new
PrintWriter
from an existingOutputStream
. This convenience constructor creates the necessary intermediateOutputStreamWriter
, which will convert characters into bytes using the default character encoding.Parameters:
out
- An output stream
autoFlush
- Aboolean
; iftrue
, theprintln
,printf
, orformat
methods will flush the output bufferSee Also: OutputStreamWriter.OutputStreamWriter(java.io.OutputStream)
Notice the autoFlush
flag only works on println
, printf
, and format
. Now, I know that printf
and format
basically do the exact same thing as print
except with more options, but I just don't see why they didn't include print
as well in the contract. Why did they make this decision?
I suspect it's because the Java authors are making assumptions about performance:
Consider the following code:
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(',');
}
}
You almost certainly would not want such a method to call flush()
after every single call. It could be a big performance hit, especially for large arrays. And, if for some reason you did want that, you could just call flush
yourself.
The idea is that printf
, format
, and println
methods are likely going to be printing a good chunk of text all at once, so it makes sense to flush after every one. But it would rarely, if ever, make sense flush after only 1 or a few characters.
After some searching, I have found a citation for this reasoning (emphasis mine):
Most of the examples we've seen so far use unbuffered I/O. This means each read or write request is handled directly by the underlying OS. This can make a program much less efficient, since each such request often triggers disk access, network activity, or some other operation that is relatively expensive.
To reduce this kind of overhead, the Java platform implements buffered I/O streams. Buffered input streams read data from a memory area known as a buffer; the native input API is called only when the buffer is empty. Similarly, buffered output streams write data to a buffer, and the native output API is called only when the buffer is full.
<snip>
It often makes sense to write out a buffer at critical points, without waiting for it to fill. This is known as flushing the buffer.
Some buffered output classes support autoflush, specified by an optional constructor argument. When autoflush is enabled, certain key events cause the buffer to be flushed. For example, an autoflush
PrintWriter
object flushes the buffer on every invocation ofprintln
orformat
.