Closing Files in Java

Learn how to properly close FileInputStream and FileOutputStream when accessing files in Java to avoid resource leaks and optimize performance.
On this page

Closing Files in Java

Excerpt

In Java, the FileInputStream and FileOutputStream classes are used to read and write raw bytes from and to files. It is important to properly close these streams after accessing files to avoid resource leaks. This article will cover how to use the close() method on FileInputStream and FileOutputStream to close streams and release system resources.

Introduction

The FileInputStream class in Java is used to read data from a file as a stream of raw bytes. This is useful for reading image files, multimedia content, and other binary data. Similarly, the FileOutputStream class allows writing raw bytes to a file.

After opening a stream and reading from or writing to a file, it is very important to close the stream. Failing to close a stream can lead to file handle and memory leaks in your application over time. The close() method is available on both FileInputStream and FileOutputStream to close a stream.

Closing FileInputStream

To close a FileInputStream after reading from a file, simply call the close() method on the stream instance:

1FileInputStream inputStream = new FileInputStream("data.bin");
2
3// read file
4
5inputStream.close();

The close() method closes the stream and releases any system resources associated with it like file handles. It is important to close the stream even if exceptions occur while reading the file to avoid resource leaks. The close() method itself does not return any value, but can throw an IOException if any error occurs while closing the stream.

Here is an example of properly closing a FileInputStream after reading a file:

 1FileInputStream inputStream = null;
 2
 3try {
 4
 5  inputStream = new FileInputStream("file.txt");
 6
 7  // read file
 8
 9  inputStream.close();
10
11} catch (IOException e) {
12
13  // handle exception
14
15} finally {
16
17  if (inputStream != null) {
18    inputStream.close();
19  }
20
21}

This ensures the stream is closed both after normal reading, and in case an exception is thrown. The stream is closed in a finally block which always executes.

Closing FileOutputStream

Similar to FileInputStream, it is important to close a FileOutputStream after writing data to a file. This is done using the same close() method:

1FileOutputStream outputStream = new FileOutputStream("data.bin");
2
3// write data to file
4
5outputStream.close();

Like with FileInputStream, this releases operating system resources like file handles. Make sure to close the stream in a finally block to ensure execution:

 1FileOutputStream outputStream = null;
 2
 3try {
 4
 5  outputStream = new FileOutputStream("file.txt");
 6
 7  // write to file
 8
 9  outputStream.close();
10
11} catch (IOException e) {
12
13  // handle exception
14
15} finally {
16
17  if (outputStream != null) {
18    outputStream.close();
19  }
20
21}

This properly closes the stream after writing, and in case of any exceptions.

Optimizations in Recent Java Versions

Several optimizations around closing streams and auto-closing resources have been added in recent Java versions:

Java VersionImprovement
Java 7Try-with-resources statement to automatically close streams
Java 9Cleaner, more efficient try-with-resources implementation
Java 11FileInputStream and FileOutputStream extend AutoCloseable
Java 16New Closeable.orElseThrow() method added

In Java 7, the try-with-resources statement was added, which allows automatic closing of streams after the statement block finishes. This ensures streams are closed even if exceptions occur:

1try (FileInputStream input = new FileInputStream("data.bin")) {
2
3  // read file
4
5} catch (Exception e) {
6
7  // handle exception
8
9}

The stream is automatically closed at the end of the try block.

Java 9 optimized the implementation of try-with-resources to be more efficient and perform better.

In Java 11, the FileInputStream and FileOutputStream classes were changed to implement the AutoCloseable interface, allowing them to be used with try-with-resources for automatic closing.

Java 16 added a new orElseThrow() method on the Closeable interface to throw exceptions while closing if needed.

Conclusion

The close() method available on FileInputStream and FileOutputStream should always be called after accessing files to avoid resource leaks. Make sure to close streams in finally blocks to ensure execution even in case of exceptions. Properly closing files leads to more robust and optimized Java programs.