Skip to main content

Section 11.5 try-with-resources

In the two printFile(…) implementations given in Listing 11.4.1 and Listing 11.4.2, we made sure to close the opened resource to ensure that we had no resource leaks. A better way to ensure suitable resources are closed is to use a newer version of try-catch called try-with-resources. This newer version of try-catch takes a closable object as an argument and closes it automatically when its block scope is exited. There is no reason to use a finally-statement or other means of checking that the resource is closed in a try-with-resources statement; Java takes of it for us.
For an object resource to be suitable for use in a try-with-resources, it must implement the AutoClosable interface, listed below. This interface includes one signature for the close() method. This is the method invoked by a try-with-resources when its block scope is exited.
public interface AutoCloseable {
    void close() throws Exception;
}
The format of a try-with-resources is exactly like a try-catch, only with a parenthesized object declaration added between the try keyword and its opening {. Because both Scanner and BufferedReader implement the AutoClosable interface, we can rewrite the printFile(…) implementations in Listing 11.4.1 and Listing 11.4.2 to use try-with-resources instead. This simplifies the code and ensures the resources will always be closed properly.
It is a best practice to use one of the following two examples as your standard way to read a file line-by-line.
// ReadFile1C.java
import java.util.Scanner;                 // Required imports
import java.io.File;
import java.io.FileNotFoundException;

public class ReadFile1C {
  public static void main(String[] args) {
    printFile("data.txt");                // Print file given path
  }

  // Utility to print a file's contents
  public static void printFile(String fileName) {
    String line;                          // Helpers to hold read line String
    File fp = new File(fileName);         // Create a new File object

    try (Scanner scn = new Scanner(fp)) { // try-with-resources
      while (scn.hasNextLine()) {         // Continue while more to read
        line = scn.nextLine();            // Read line from file
        System.out.println( line );       // Print line
      }
    } catch( FileNotFoundException e ) {  // Handle checked exception
      System.out.println(e);
    }
  }
}
Listing 11.5.1. ReadFile1C.java
// ReadFile2C.java
import java.io.*;                         // Required imports

public class ReadFile2C {
  public static void main(String[] args) {
    printFile("data.txt");                // Print file given path
  }

  // Utility to print a file's contents
  public static void printFile(String fileName) {
    String line;                          // Helper variables
    
    // Open a file using try-with-resources notation
    try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
                                          // Read and assign line until null
      while ( (line = br.readLine()) != null ) {
        System.out.println(line);         // Print line
      }
    } 
    catch (FileNotFoundException ex) {    // Thrown by FileReader
      System.out.println( "File was not found: " + fileName );
    } 
    catch (IOException ex){               // Thrown by BufferedReader
      System.out.println(ex);
    }
  }
}
Listing 11.5.2. ReadFile2C.java