Closing Java InputStreams

JavaInputstream

Java Problem Overview


I have some questions about the usage of the close() method when using Java InputStreams. From what I see and read from most developers, you should always explicitly call close() on an InputStream when it is no longer needed. But, today I was looking into using a Java properties file, and every example I have found has something like this:

Properties props = new Properties();
try {
    props.load(new FileInputStream("message.properties"));
    //omitted.
} catch (Exception ex) {}

With the above example, there is no way to explicitly call close() because the InputStream is unreachable after it is used. I have seen many similar uses of InputStreams even though it seems to contradict what most people say about explicitly closing. I read through Oracle's JavaDocs and it does not mention if the Properties.load() method closes the InputStream. I am wondering if this is generally acceptable or if it is preferred to do something more like the following:

Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
} finally {
    try {
        fis.close();
    } catch (IOException ioex) {
        //omitted.
    }
}

Which way is better and/or more efficient? Or does it really matter?

Java Solutions


Solution 1 - Java

The Properties class wraps the input stream in a LineReader to read the properties file. Since you provide the input stream, it's your responsibility to close it.

The second example is a better way to handle the stream by far, don't rely on somebody else to close it for you.

One improvement you could make is to use IOUtils.closeQuietly()

to close the stream, e.g.:

Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
} finally {
    IOUtils.closeQuietly(fis);
}

Solution 2 - Java

I would go with a try-with-resources (at least for Java 7+):

Properties props = new Properties();

try(InputStream fis = new FileInputStream("message.properties")) {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
}

The close() call should be automatically called when the try block is exited.

Solution 3 - Java

The examples in the Properties Tutorial close the FileInputStream explicitly after loading, so I think it's safe to assume that the load method isn't responsible for it, you are.

// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();

Just for reference, I checked the Apache Harmony implementation of Properties, and it does not close the stream on load.

Solution 4 - Java

If you're using Java 7+ you can use this:

try(InputStream is = new FileInputStream("message.properties")) {
    // ...
}

Solution 5 - Java

It doesn't mention in the documentation that props.load would close the input stream. You should close the input stream manually in a finally block like you suggest.

It isn't normal for a function to close an InputStream. The same convention applies as with memory in non-garbage-collected languages: If possible, the one who opens the stream should close the stream. Otherwise, it's very easy to leave a stream open (you think a function's going to close it, but it doesn't, or something...)

Solution 6 - Java

It looks like the first code sample ends up relying on the finalize method in FileInputStream to actually close the file. I would say your second example is better, even though in both cases the file does get closed.

There are cases like the Byte streams where close does nothing and can be omitted, otherwise I think it's better to explicitly close the file in a finally block. If you open it, you close it.

There is a book on Oracle's site called Java Platform Performance that discusses finalizers in its appendix, it says:

> You are almost always better off doing your own cleanup instead of relying on a finalizer. Using a finalizer can also leave behind critical resources that won't be recovered for an indeterminate amount of time. If you are considering using a finalizer to ensure that important resources are freed in a timely manner, you might want to reconsider.

Solution 7 - Java

Let me add a little something to other people's answers.

If you can import [Apache Commons IO][1], you could make use of the ever-so-handy [AutoCloseInputStream][2]s classes: you wrap your InputStream and then you just use your wrapped instance and it gets automatically closed as soon as the end of input has been reached or when the stream is explicitly closed, whichever comes first.

[1]: http://commons.apache.org/io/ "Apache Commons IO 2.4" [2]: http://commons.apache.org/io/api-2.4/org/apache/commons/io/input/AutoCloseInputStream.html "AutoCloseInputStream class"

Solution 8 - Java

Because FileInputStream implements finalize() and invoke close() in `finalize.

So when not so frequently used, there is no need to close FileInputStream

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason WatkinsView Question on Stackoverflow
Solution 1 - JavaJonView Answer on Stackoverflow
Solution 2 - JavaDaniel VoinaView Answer on Stackoverflow
Solution 3 - JavaBill the LizardView Answer on Stackoverflow
Solution 4 - Javakwo2002View Answer on Stackoverflow
Solution 5 - JavaAdrian SmithView Answer on Stackoverflow
Solution 6 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 7 - JavaUnai ViviView Answer on Stackoverflow
Solution 8 - JavalhlView Answer on Stackoverflow