8

I have the following Java Class that does one thing, fires out values from config.properties.

When it comes time to close the fileInputStream, I think I read on Wikipedia that it is good to have it in a finally block. Because it honestly works just fine in try/catch block.

Can you show me correction to get fileInputStream.close() in a finally section?

ConfigProperties.java package base;

import java.io.FileInputStream;
import java.util.Properties;

public class ConfigProperties {

    public FileInputStream fileInputStream;
    public String property;

    public String getConfigProperties(String strProperty) {

        Properties configProperties = new Properties();
        try {

            fileInputStream = new FileInputStream("resources/config.properties");
            configProperties.load(fileInputStream);
            property = configProperties.getProperty(strProperty);
            System.out.println("getConfigProperties(" + strProperty + ")");

            // use a finally block to close your Stream.
            // If an exception occurs, do you want the application to shut down?

        } catch (Exception ex) {
            // TODO
            System.out.println("Exception: " + ex);
        }
        finally {
            fileInputStream.close();
        }

        return property;
    }
}

Is the solution only to do as Eclipse suggests and do this in the finally block?

finally {
    try {
        fileInputStream.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
giannis christofakis
  • 8,201
  • 4
  • 54
  • 65
JoJo
  • 4,643
  • 9
  • 42
  • 65
  • 1
    FYI: commons-io has a nice function: IOUtils.closeQuietly() that will take care of the try/catch on the close. Your code will look much nicer :) Keep in mind that this function does not give you the chance to respond to the IOException, but usually people don't do that and ignore the exception anyway. If you need to respond, make your own utility method which logs or prints a stack trace or whatever you need to do. – Matt Jul 24 '12 at 00:42

4 Answers4

25

Yes, that is the common pre-Java 7 solution. However, with the introduction of Java 7, there are now try-with-resource statements which will automatically close any declared resources when the try block exits:

try (FileInputStream fileIn = ...) {
    // do something
} // fileIn is closed
catch (IOException e) {
    //handle exception
}
Jeffrey
  • 44,417
  • 8
  • 90
  • 141
11

The standard approach is:

FileInputStream fileInputStream = null;
try {
    fileInputStream = new FileInputStream(...);
    // do something with the inputstream
} catch (IOException e) {
    // handle an exception
} finally { //  finally blocks are guaranteed to be executed
    // close() can throw an IOException too, so we got to wrap that too
    try {
        if (fileInputStream != null) {
            fileInputStream.close();
        }        
    } catch (IOException e) {
        // handle an exception, or often we just ignore it
    }
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
10

Because FileInputStream.close() throws an IOException, and the finally{} block doesn't catch exceptions. So you need to either catch it or declare it in order to compile. Eclipse's suggestion is fine; catch the IOException inside the finally{} block.

Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • You can also use the [IOUtils.closeQuietly()](http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.Closeable)) method from Commons IO. It wraps the close method to drop all of the IOExceptions that are thrown. Cleaner than having another try/catch block. – Jonathan B Sep 12 '13 at 02:07
0

It's a good habit to close streams because what it does in background it's called buffering, meaning that it does not free the internal buffer and does not free the file descriptor.

debugger
  • 1
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/33359338) – habrewning Dec 12 '22 at 18:05