Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing inputstreams in Java

I have the following piece of code in a try/catch block

 InputStream inputstream = conn.getInputStream();
 InputStreamReader inputstreamreader = new  InputStreamReader(inputstream);
 BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

My question is that when I have to close these streams in the finally block, do I have to close all the 3 streams or just closing the befferedreader will close all the other streams ?

like image 602
comatose Avatar asked Jun 29 '12 14:06

comatose


People also ask

Do I need to close InputStream java?

getResourceAsStream("myconffile. properties"); In docs: The close method of InputStream does nothing.

What is the right way to close the streams in java?

If close() method of input stream will throw an Exception then output stream will not be closed, i.e. fos. close() will not even execute if fis. close() throws exception. This means the file descriptor held by OutputStream will never release causing a resource leak in the Java program.

How do I close InputStream after returning?

What you can do is put a close() method on your class which cleans up any open file handlers, connections, etc., and require the user of the class to be responsible for calling close() .

Do I need to close Fileoutputstream?

No. It is not require to close other components.


3 Answers

By convention, wrapper streams (which wrap existing streams) close the underlying stream when they are closed, so only have to close bufferedreader in your example. Also, it is usually harmless to close an already closed stream, so closing all 3 streams won't hurt.

like image 157
casablanca Avatar answered Sep 21 '22 16:09

casablanca


Normally it is ok to just close the most outer stream, because by convention it must trigger close on the underlying streams.

So normally code looks like this:

BufferedReader in = null;  try {     in = new BufferedReader(new InputStreamReader(conn.getInputStream()));     ...     in.close(); // when you care about Exception-Handling in case when closing fails } finally {     IOUtils.closeQuietly(in); // ensure closing; Apache Commons IO } 

Nevertheless there may be rare cases where an underlying stream constructor raises an exception where the stream is already opened. In that case the above code won't close the underlying stream because the outer constructor was never called and in is null. So the finally block does not close anything leaving the underlying stream opened.

Since Java 7 you can do this:

    try (OutputStream out1 = new ...; OutputStream out2 = new ...) {         ...         out1.close(); //if you want Exceptions-Handling; otherwise skip this         out2.close(); //if you want Exceptions-Handling; otherwise skip this                 } // out1 and out2 are auto-closed when leaving this block 

In most cases you do not want Exception-Handling when raised while closing so skip these explicit close() calls.

Edit Here's some code for the non-believers where it is substantial to use this pattern. You may also like to read Apache Commons IOUtils javadoc about closeQuietly() method.

    OutputStream out1 = null;     OutputStream out2 = null;      try {         out1 = new ...;         out2 = new ...;          ...          out1.close(); // can be skipped if we do not care about exception-handling while closing         out2.close(); // can be skipped if we ...     }     finally {         /*          * I've some custom methods in my projects overloading these          * closeQuietly() methods with a 2nd param taking a logger instance,           * because usually I do not want to react on Exceptions during close           * but want to see it in the logs when it happened.          */         IOUtils.closeQuietly(out1);         IOUtils.closeQuietly(out2);     } 

Using @Tom's "advice" will leave out1 opened when creation of out2 raises an exception. This advice is from someone talking about It's a continual source of errors for obvious reasons. Well, I may be blind, but it's not obvious to me. My pattern is idiot-safe in every use-case I can think of while Tom's pattern is error-prone.

like image 35
Fabian Barney Avatar answered Sep 20 '22 16:09

Fabian Barney


Closing the outermost one is sufficient (i.e. the BufferedReader). Reading the source code of BufferedReader we can see that it closes the inner Reader when its own close method is called:

513       public void close() throws IOException {
514           synchronized (lock) {
515               if (in == null)
516                   return;
517               in.close();
518               in = null;
519               cb = null;
520           }
521       }
522   }
like image 32
Tudor Avatar answered Sep 22 '22 16:09

Tudor