Does it make sense to always wrap an InputStream as BufferedInputStream, when I know whether the given InputStream is something other than buffered? For e.g:
InputStream is = API.getFromSomewhere()
if(!(is instanceof BufferedInputStream))
return new BufferedInputStream(is);
return is;
No.
It makes sense if you are likely to perform lots of small reads (one byte or a few bytes at a time), or if you want to use some of the higher level functionality offered by the buffered APIs; for example the
BufferedReader.readLine()
method.However, if you are only going to perform large block reads using the
read(byte[])
and / orread(byte[], int, int)
methods, wrapping theInputStream
in aBufferedInputStream
does not help.(In response to @Peter Tillman's comment on his own Answer, the block read use-cases definitely represent more than 0.1% of uses of
InputStream
classes!! However, he is correct in the sense that it is usually harmless to use a buffered API when you don't need to.)You may not always need buffering so, for that, the answer would be No, in some cases it's just overhead.
There is another reason it is "No" and it can be more serious.
BufferedInputStream
(orBufferedReader
) can cause unpredictable failures when used with network socket when you also have enabled a timeout on the socket. The timeout can occur while reading a packet. You would no longer be able to access the data that were transferred to that point - even if you knew that there was some non-zero number of bytes (seejava.net.SocketTimeoutException
which is a subclass ofjava.io.InterruptedIOException
so hasbytesTransferred
variable available).If you are wondering how a socket timeout could occur while reading, just think of calling the
read(bytes[])
method and the original packet that contains the message ended up being split but one of the partial packets is delayed beyond the timeout (or the remaining portion of the timeout). This can happen more frequently when wrapped again in something that implementsjava.io.DataInput
(any of the reads for multiple byte values, likereadLong()
orreadFully()
or theBufferedReader.readLine()
method.Note that
java.io.DataInputStream
also is a bad candidate for socket streams that have a timeout since it doesn't behave well with timeout exceptions either.It also depends on how you are going to read from the InputStream. If you are going to read it a character/byte at a time (ie read()), then the BufferedInputStream will reduce your overheads by queitly doing bulk reads on your behalf. If you are going to read it into a 4k or 8k byte/char array a block at a time then the BuffredInputStream probably won't benefit you.
I would not do that, I would leave it at the highest abstraction level possible. If you are not going to use the mark and reset capabilities of a BufferedStream, why bother wrapping it?
If a consumer needs it, it is better to wrap it there.