Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disposing streams in Java

Tags:

java

stream

In C#, I almost always use the using pattern when working with stream objects. For example:

using (Stream stream = new MemoryStream())
{
    // do stuff
}

By using the using block, we ensure that dispose is called on the stream immediately after that code bock executes.

I know Java doesn't have the equivalent of a using keyword, but my question is that when working with an object like a FileOutputStream in Java, do we need to do any housekeeping to make sure it gets disposed? I was looking at this code example, and I noticed they don't do any.

I just wondered what the best practice was for Java in handling disposing streams, or if it's good enough to let the garbage collector handle it.

like image 434
dcp Avatar asked Feb 15 '10 19:02

dcp


People also ask

What are the 3 types of streams in Java?

Java provides three predefined stream objects: in, out, and err, defined in the System class of the java.

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

The java. io. InputStream. close() method closes this stream and releases any system resources associated with the stream.

Is it good to use streams in Java?

There are a lot of benefits to using streams in Java, such as the ability to write functions at a more abstract level which can reduce code bugs, compact functions into fewer and more readable lines of code, and the ease they offer for parallelization.

Do input streams need to be closed Java?

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.


3 Answers

generally, you have to do the following:

InputStream stream = null;
try {
   // IO stuff - create the stream and manipulate it
} catch (IOException ex){
  // handle exception
} finally {
  try {
     stream.close();
  } catch (IOException ex){}
}

But apache commons-io provides IOUtils.closeQuietly(stream); which is put in the finally clause to make it a little less-ugly. I think there will be some improvement on that in Java 7.

Update: Jon Skeet made a very useful comment, that the actual handling of the exception is rarely possible to happen in the class itself (unless it is simply to log it, but that's not actually handling it). So you'd better declare your method throw that exception up, or wrap it in a custom exception (except for simple, atomic operations).

like image 146
Bozho Avatar answered Sep 30 '22 17:09

Bozho


The feature you want was indeed introduced in Java 7, under the name "try-with-resources statement" (also known as automatic resource management (ARM)). Here is the code:

try (InputStream in = new FileInputStream("foo.txt")) {
    ...
}  // This finally calls in.close()
like image 25
Nayuki Avatar answered Sep 30 '22 17:09

Nayuki


There's (sadly) no equivalent of the using statement in Java, although there have been some thoughts about including something similar in Java 7. (I think last time I looked they were "out", but I find it hard to keep up with the status of features in Java 7.)

Baically you need a try/finally block:

InputStream stream = new FileInputStream(...);
try { 
    ...
} finally {
    stream.close();
}

There's then the problem of what to do with the IOException in the case of the close() failing, and the problem of an exception there "overwriting" any exception thrown by the main body of the code - although the latter is a problem in .NET too.

Guava makes this slightly easier with the Closeables class, with static close and closeQuietly methods which will deal with stream being null (in the case where you declare the variable before the block but assign the value within the try block).

like image 23
Jon Skeet Avatar answered Sep 30 '22 16:09

Jon Skeet