Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always wrap an InputStream as BufferedInputStream?

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;
like image 586
geejay Avatar asked Jun 03 '10 07:06

geejay


People also ask

Do I need to close InputStream?

You do need to close the input Stream, because the stream returned by the method you mention is actually FileInputStream or some other subclass of InputStream that holds a handle for a file. If you do not close this stream you have resource leakage.

What happens if you don't close an InputStream?

The operating system will only allow a single process to open a certain number of files, and if you don't close your input streams, it might forbid the JVM from opening any more.

Why is BufferedInputStream faster?

With a BufferedInputStream , the method delegates to an overloaded read() method that reads 8192 amount of bytes and buffers them until they are needed. It still returns only the single byte (but keeps the others in reserve). This way the BufferedInputStream makes less native calls to the OS to read from the file.

What is the difference between InputStream and BufferedInputStream?

DataInputStream is a kind of InputStream to read data directly as primitive data types. BufferedInputStream is a kind of inputStream that reads data from a stream and uses a buffer to optimize speed access to data.


3 Answers

Does it make sense to always wrap an InputStream as BufferedInputStream, when I know whether the given InputStream is something other than buffered?

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 / or read(byte[], int, int) methods, wrapping the InputStream in a BufferedInputStream 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.)

like image 187
Stephen C Avatar answered Oct 11 '22 12:10

Stephen C


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.

like image 33
Peter Tillemans Avatar answered Oct 11 '22 11:10

Peter Tillemans


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 (or BufferedReader) 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 (see java.net.SocketTimeoutException which is a subclass of java.io.InterruptedIOException so has bytesTransferred 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 implements java.io.DataInput (any of the reads for multiple byte values, like readLong() or readFully() or the BufferedReader.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.

like image 3
Kevin Brock Avatar answered Oct 11 '22 10:10

Kevin Brock