Java Automatically Close File

In the previous chapter, the example programs have made an explicit calls to close() to close a file once it is no longer needed.

As discussed, this is the way files were closed when using versions of Java prior to JDK 7. Although this approach is however valid and useful, JDK 7 added a new feature that offers another way to handle resources, such as file streams, by automating the closing procedure. This feature, sometimes referred to as automatic resource management (ARM), is based on an expanded version of the try statement.

Automatic Resource Management in Java

The main advantage of automatic resource management is that it prevents the situations in which a file (or other resource) is unknowingly not released after it is no longer needed.

As explained, forgetting to close a file can result in memory leaks, and could lead to the other problems.

Automatic resource management is based on an expanded form of the try statement. Below is its general form:

try(resource-specification) {
   // use the resource
}

Here, resource-specification is a statement, declares and initializes a resource, such as a file stream. It consists of a variable declaration in which the variable is initialized with a reference to the object being managed. When the try block ends, the resource is automatically released. In case of a file, this means that the file is automatically closed. Therefore, there is no need to call the close() explicitly. Of course, this form of try can also include catch and finally clauses. This new form of the try is called the try-with-resources statement.

The Java try-with-resources statement can be used only with those resources that implement the AutoCloseable interface defined by the package java.lang. This interface defines the close() method.

The AutoCloseable is inherited by the Closeable interface in the package java.io. Both interfaces are implemented by the stream classes. Thus, try-with-resources can be used when working with streams, including file streams.

Java Automatically Close a File Example

As a first example of automatically closing a file, here is a reworked version of the FileOperationDemo (shown in previous chapter) program that uses it:

/* Java Program Example - Java Automatically Closing a File
 * This version of FileOperationDemo program uses a 
 * try-with-resources statement to automatically close a
 * file after/when it is no longer needed
 * 
 * Remember, this code requires the JDK 7 or later
 */

import java.io.*;

class FileOperationDemo
{
    public static void main(String args[])
    {
        
        int i;
        
        /* first, confirm that a filename has been specified */
        if(args.length != 1) {
            System.out.println("Usage : FileOperationDemo filename");
            return;
            
        }
        
        /* the following code uses a try-with-resources statement
         * to open a file and then automatically close it when
         * the try block is left.
         */
        try(FileInputStream fin = new FileInputStream(args[0])) {
            
            do {
                i = fin.read();
                
                if(i != -1)
                    System.out.print((char) i);
                    
            } while(i != -1);
            
        } catch(FileNotFoundException e) {
            System.out.println("File Not Found..!!");
            
        } catch(IOException e) {
            System.out.println("An I/O Error Occurred..!!");
            
        }
        
    }
}

In this program, pay special attention to how the file is opened within the try statement:

try(FileInputStream fin = new FileInputStream(args[0])) {

Notice here, how the resource-specification portion of the try declares a FileInputStream called fin, which is assigned the reference to the file opened by its constructor. Therefore, in this version of program, the variable fin is local to the try block only, being created when the try is entered. When the try is left, the stream associated with the fin is automatically closed by an implicit call to the close(). You don't need to call the method close() explicitly, means that you cannot forget to close the file. This is the key advantage of using the try-with-resources.

It is important to realize that the resource declared in the try statement is implicitly final. This means that you can't assign to the resource after it has been created. Also, the scope of the resource is limited to the try-with-resources statement.

You can handle more than one resource within a single try statement. To do so, simply separate each resource specification with a semicolon.

Here this program shows an example. It reworks the FileOperationDemo (for copy file, shown in earlier chapter) program so that it uses single try-with-resources statement to manage both fin and fout.

/* Java Program Example - Java Automatically Close a File
 * A version of file FileOperationDemo (to copy file) that uses
 * the try-with-resources
 * This illustrates the two resources (in this case files)
 * being managed by single try statement
 */

import java.io.*;

class FileOperationDemo
{
    public static void main(String args[])
    {
        
        int i;
        
        /* first, confirm that both the files have been specified */
        if(args.length != 2)
        {
            System.out.println("Usage : FileOperationDemo from to");
            return;
        }
        
        /* open and manage the two files via the try statement */
        try(FileInputStream fin = new FileInputStream(args[0]);
            FileOutputStream fout = new FileOutputStream(args[1]))
        {
            
            do
            {
                i = fin.read();
                
                if(i != -1)
                    fout.write(i);
            } while(i != -1);
            
        } catch(IOException e) {
            System.out.println("I/O Error : " + e);
        }
        
    }
}

In this Java program, notice how the input and output files are opened within the try block:

try(FileInputStream fin = new FileInputStream(args[0]);
    FileOutputStream fout = new FileOutputStream(args[1]))
{
    // ...

After this try block ends, the fin and fout both will have been closed. If you compare this version of the program to the old version, you will see that it is much shorter. The ability to streamline source code is a side-benefit of automatic resource management.

More Examples

Here are some examples related to files in Java, you can go for.

Java Online Test


« Previous Tutorial Next Tutorial »