Java try-with-resources Statement with Examples

In this article, we will discuss the try-with-resources statement in depth with examples, how it works, demonstration of try-with-resources statement and more hands on examples using File IO classes.

What We will Learn?

  1. What is try-with-resources statement?
  2. Overview of java.lang.AutoCloseable Interface
  3. Working of try-with-resources statement with BufferedReader Example
  4. Resource closing using finally block(Prior to Java SE 7)
  5. Declare one or more resources in a try-with-resources statement
  6. Custom Resource object close examples
  7. try-with-resources Statement with File IO Examples

1. What is try-with-resources statement?

The try-with-resources statement is a try statement that declares one or more resources.

What is a resource?

resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement.
Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

2. java.lang.AutoCloseable Interface

An object that may hold resources (such as file or socket handles) until it is closed. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header. This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.
The following is the source code of AutoCloseable interface:
public interface AutoCloseable {
    void close() throws Exception;
}
Note that it throws Exception if this resource cannot be closed.

3. Working of try-with-resources Statement with BufferedReader Example

The following example reads the lines from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it.
The class diagram shows the  hierarchy of BufferedReader class.
public class BufferedReaderExample {
 public static void main(String[] args) {
  try (FileReader fr = new FileReader("C:/workspace/java-io-guide/sample.txt");
    BufferedReader br = new BufferedReader(fr);) {
   String sCurrentLine;

   while ((sCurrentLine = br.readLine()) != null) {
    System.out.println(sCurrentLine);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).
BufferedReader internally implements the Closeable interface, which extends the AutoCloseableinterface. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header hence the BufferedReader resource class is automatically closed by calling close() method of an AutoCloseable object.

4. Resource closing using finally block(Prior to Java SE 7)

Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly.
The following example uses a finally block instead of a try-with-resources statement:
import java.io.BufferedReader;

import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {
 public static void main(String[] args) {
  BufferedReader br = null;
  try {
   br = new BufferedReader(new FileReader("sample.txt"));
   String sCurrentLine;
   while ((sCurrentLine = br.readLine()) != null) {
    System.out.println(sCurrentLine);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
  finally{
   if(br != null){
    try {
     br.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }
 }
}
Create a file with name 'sample.txt' and add few lines to this file and run above program produces output as:
There is some content in file 
newline added to existing file

5. Declare one or more resources in a try-with-resources statement

We may declare one or more resources in a try-with-resources statement. Let's take an example of how to compress a single file in ZIP format example. These are resources where used in this example.
  1. Read file with “FileInputStream”
FileInputStream in = new FileInputStream("C:/Project_Work/samples/sample.txt");
  1. Create output zip file with "FileOutputStream"
FileOutputStream fos = new FileOutputStream("C:/Project_Work/samples/src_sample.zip")
  1. Add the file name to “ZipEntry” and output it to “ZipOutputStream“
Read a file “C:/Project_Work/samples/sample.txt” and compress it into a zip file – “C:/Project_Work/samples/src_sample.zip“.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * This Java program demonstrates how to compress single file in ZIP format.
 * @author javaguides.net
 */

public class CompressZipFile {
 public static void main(String[] args) {

  try (FileOutputStream fos = new FileOutputStream("C:/Project_Work/samples/src_sample.zip");
    ZipOutputStream zos = new ZipOutputStream(fos);
    FileInputStream in = new FileInputStream("C:/Project_Work/samples/sample.txt");) {
   ZipEntry ze= new ZipEntry("sample.txt");
      zos.putNextEntry(ze);
   byte[] buffer = new byte[1024];
   int len;
   while ((len = in.read(buffer)) > 0) {
    zos.write(buffer, 0, len);
   }

  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

6. Custom Resource object close examples

Here we will demonstrate how resources are auto closed by creating custom ResourceDemo and ResourceDemo1 classes which implements Autoclosable Interface.
public class TryWithResourceExample {
 public static void main(String s[]) {
  // note the order of opening the resources
  try (ResourceDemo d = new ResourceDemo(); ResourceDemo1 d1 = new ResourceDemo1()) {
   int x = 10 / 0;
   d.show();
   d1.show1();
  } catch (ArithmeticException e) {
   System.out.println(e);
  }
 }
}

// custom resource 1
class ResourceDemo implements AutoCloseable {
 void show() {
  System.out.println("inside show");
 }

 public void close() {
  System.out.println("close from resourcedemo");
 }
}

// custom resource 2
class ResourceDemo1 implements AutoCloseable {
 void show1() {
  System.out.println("inside show1");
 }

 public void close() {
  System.out.println("close from resourcedemo1");
 }
}
Output:
close from resourcedemo1
close from resourcedemo
java.lang.ArithmeticException: / by zero
Note that ArithmeticException exception is thrown after closing resources. This also an example to declare one or more resources with a try-with-resources statement.

7. try-with-resources Statement with File IO Examples

Let's discuss a few more examples using File IO classes.

a try-with-resources statement with BufferedInputStream example

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class BufferedInputStreamExample {
 public static void main(String[] args) {
  try( FileInputStream fin=new FileInputStream("sample.txt");    
       BufferedInputStream bin=new BufferedInputStream(fin); ){
   int i;    
      while((i=bin.read())!=-1){    
       System.out.print((char)i);    
      }    
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

try-with-resources statement with BufferedOutputStream Example

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class BufferedOutputStreamExample {
 public static void main(String[] args) {
  File file = new File("sample.txt");
  String content = "This is the text content";

  try (OutputStream out = new FileOutputStream(file);
    BufferedOutputStream bout = new BufferedOutputStream(out);) {

   // if file doesn't exists, then create it
   if (!file.exists()) {
    file.createNewFile();
   }
   // get the content in bytes
   bout.write(content.getBytes());
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

try-with-resources statement with DataInputStream example

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class DataInputStreamExample {
 public static void main(String[] args) {
  try(InputStream input = new FileInputStream("sample.txt");  
     DataInputStream inst = new DataInputStream(input);){  
     int count = input.available(); 
     
     byte[] ary = new byte[count];  
     inst.read(ary);  
     for (byte bt : ary) {  
       char k = (char) bt;  
       System.out.print(k+"-");  
     }  
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

try-with-resources statement with FileWritter example

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileWritterExample {
 public static void main(String[] args) {
  File file = new File("sample.txt");
  String content = "This is the text content";

  try (FileWriter fop = new FileWriter(file)) {

   // if file doesn't exists, then create it
   if (!file.exists()) {
    file.createNewFile();
   }
   fop.write(content);

  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
One more additional point is the close method of the Closeable interface throws exceptions of type IOException while the close method of the AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close method to throw specialized exceptions, such as IOException, or no exception at all.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Comments