What are the differences (if any) between the following two buffering approaches?
Reader r1 = new BufferedReader(new InputStreamReader(in, \"UTF-8\"), bufferSize
In response to Ross Studtman's question in the comment above (but also relevant to the OP):
BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputSream(inputStream), "UTF-8"));
The BufferedInputStream
is superfluous (and likely harms performance due to extraneous copying). This is because the BufferedReader
requests characters from the InputStreamReader
in large chunks by calling InputStreamReader.read(char[], int, int)
, which in turn (through StreamDecoder
) calls InputStream.read(byte[], int, int)
to read a large block of bytes from the underlying InputStream
.
You can convince yourself that this is so by running the following code:
new BufferedReader(new InputStreamReader(new ByteArrayInputStream("Hello world!".getBytes("UTF-8")) {
@Override
public synchronized int read() {
System.err.println("ByteArrayInputStream.read()");
return super.read();
}
@Override
public synchronized int read(byte[] b, int off, int len) {
System.err.println("ByteArrayInputStream.read(..., " + off + ", " + len + ')');
return super.read(b, off, len);
}
}, "UTF-8") {
@Override
public int read() throws IOException {
System.err.println("InputStreamReader.read()");
return super.read();
}
@Override
public int read(char[] cbuf, int offset, int length) throws IOException {
System.err.println("InputStreamReader.read(..., " + offset + ", " + length + ')');
return super.read(cbuf, offset, length);
}
}).read(); // read one character from the BufferedReader
You will see the following output:
InputStreamReader.read(..., 0, 8192)
ByteArrayInputStream.read(..., 0, 8192)
This demonstrates that the BufferedReader
requests a large chunk of characters from the InputStreamReader
, which in turn requests a large chunk of bytes from the underlying InputStream
.