Which means the InputStreamReader is never closed

Eh? In your code it is... And it will certainly handle the .close() of your resource stream as well. See below for more details...

As @SotiriosDelimanolis mentions however you can declare more than one resource in the "resource block" of a try-with-resources statement.

You have another problem here: .getResourceAsStream() can return null; you may therefore have an NPE.

I'd do this if I were you:

final URL url = ModelCodeGenerator.class.getClassLoader()
    .getResource("/model.java.txt");

if (url == null)
    throw new IOException("resource not found");

try (
    final InputStream in = url.openStream();
    final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
    // manipulate resources
}

There is a very important point to consider however...

Closeable does extend AutoCloseable, yes; in fact it only differs, "signature wise", by the exception thrown (IOException vs Exception). But there is a fundamental difference in behavior.

From the javadoc of AutoCloseable's .close() (emphasis mine):

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.

And indeed, the javadoc of Closeable is clear about this:

Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.

You have two very important points:

  • by contract, a Closeable also takes care of all resources associated with it; so, if you close a BufferedReader which wraps a Reader which wraps an InputStream, all three are closed;
  • should you call .close() more than once, there is no further side effect.

This also means, of course, that you can choose the paranoid option and keep a reference to all Closeable resources and close them all; beware however if you have AutoCloseable resources into the mix which are not Closeable!

Answer from fge on Stack Overflow
Top answer
1 of 2
20

Which means the InputStreamReader is never closed

Eh? In your code it is... And it will certainly handle the .close() of your resource stream as well. See below for more details...

As @SotiriosDelimanolis mentions however you can declare more than one resource in the "resource block" of a try-with-resources statement.

You have another problem here: .getResourceAsStream() can return null; you may therefore have an NPE.

I'd do this if I were you:

final URL url = ModelCodeGenerator.class.getClassLoader()
    .getResource("/model.java.txt");

if (url == null)
    throw new IOException("resource not found");

try (
    final InputStream in = url.openStream();
    final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
    // manipulate resources
}

There is a very important point to consider however...

Closeable does extend AutoCloseable, yes; in fact it only differs, "signature wise", by the exception thrown (IOException vs Exception). But there is a fundamental difference in behavior.

From the javadoc of AutoCloseable's .close() (emphasis mine):

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.

And indeed, the javadoc of Closeable is clear about this:

Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.

You have two very important points:

  • by contract, a Closeable also takes care of all resources associated with it; so, if you close a BufferedReader which wraps a Reader which wraps an InputStream, all three are closed;
  • should you call .close() more than once, there is no further side effect.

This also means, of course, that you can choose the paranoid option and keep a reference to all Closeable resources and close them all; beware however if you have AutoCloseable resources into the mix which are not Closeable!

2 of 2
6

But this seems worse. If InputStreamReader throws for some reason, the InputStream won't ever be closed, right?

That's right (although unlikely, the InputStreamReader constructor doesn't really do much).

The try-with-resources lets you declare as many resources as you'd like. Declare one for the wrapped resource, and another for the InputStreamReader.

try (InputStream in = ModelCodeGenerator.class
             .getClassLoader()
             .getResourceAsStream("/model.java.txt");
    InputStreamReader reader = new InputStreamReader(in)) {...}

Note that getResourceAsStream can potentially return null, which would cause the InputStreamReader constructor to throw a NullPointerException. If you want to deal with that differently, adapt how you retrieve the resource that's meant to be wrapped.

The tutorial linked above presents this example

try (
    java.util.zip.ZipFile zf =
         new java.util.zip.ZipFile(zipFileName);
    java.io.BufferedWriter writer = 
        java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {

with the explanation

In this example, the try-with-resources statement contains two declarations that are separated by a semicolon: ZipFile and BufferedWriter. When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order. Note that the close methods of resources are called in the opposite order of their creation.

🌐
Jenkov
jenkov.com › tutorials › java-exception-handling › try-with-resources.html
Java Try With Resources
August 25, 2019 - The Java try with resources construct, AKA Java try-with-resources, is an exception handling mechanism that can automatically close resources like a Java InputStream or a JDBC Connection when you are done with them.
🌐
Baeldung
baeldung.com › home › java › core java › java – try with resources
Java - Try with Resources | Baeldung
May 11, 2024 - A quick and practical guide to how we can use the try-with-resources functionality introduced in Java 7 to auto-close resources and simplify our syntax.
🌐
Oracle
docs.oracle.com › javase › tutorial › essential › exceptions › tryResourceClose.html
The try-with-resources Statement (The Java™ Tutorials > Essential Java Classes > Exceptions)
See Java Language Changes for a ... and removed or deprecated options for all JDK releases. The try-with-resources statement is a try statement that declares one or more resources....
🌐
Medium
medium.com › @reetesh043 › using-try-with-resources-in-java-simplifying-resource-management-bd9ed8cc8754
Try-With-Resources In Java: Simplifying Resource Management | by Reetesh Kumar | Medium
January 10, 2024 - In these examples, the InputStream and OutputStream objects are both automatically closed when the try block exits, regardless of whether an exception is thrown. This ensures that resources are always properly released, even in the event of an error.
🌐
Waiting for Code
waitingforcode.com › home › java
Instruction try-with-resources on waitingforcode.com - Java blog posts
July 27, 2014 - Java's solution consists to put stream construction inside try block, as below: try (FileInputStream firstStream = new FileInputStream("/home/bartosz/myInputStream")) { // do something with defined InputStream } In this code, our FileInputStream will be closed automatically by Java.
🌐
Orkhan Huseynli
orkhan-huseyn.github.io › 2020 › 03 › 26 › javas-try-with-resources
Java's try with resources
November 5, 2022 - If returned values is less than 0 (zero) then the stream is ended. Since the InputStream is for reading binary data, we also cast the integer value to byte. Now, the above code is somehow complete, but ignores an important point: the stream is not closed after reading from it. We can close it in try-catch’s finally block.
🌐
Medium
medium.com › thefreshwrites › how-to-use-try-with-resource-in-java-9c0b4ae48d21
How To Use Try With Resource In Java | Exception Handing | by Mouad Oumous | The Fresh Writes | Medium
February 17, 2024 - The Java try with resources construct, AKA Java try-with-resources, is an exception handling mechanism that can automatically close resources like a Java InputStream or a JDBC Connection when you are done with them.
🌐
Veracode
veracode.com › blog › managing-appsec › exception-handling-try-resources-statement-java-7
Exception Handling with Try with Resources Statement in Java 7 | Veracode
September 6, 2015 - In this article, we will have a look at how try-with-resources can avoid nested blocks and help correctly close multiple resources. Consider the following snippet of code. We are trying to copy the contents of the input file into the output file using I/O streams. public void copy() throws FileNotFoundException { InputStream input = new FileInputStream("in.txt"); OutputStream output = new FileOutputStream("out.txt"); byte[] buffer = new byte[1024]; try { try { while (-1 != input.read(buffer)) { output.write(buffer); } } catch (IOException ex) { Logger.getLogger(Easy.class.getName()).log(Level.SEVERE, null, ex); } finally { input.close(); output.close(); } } catch (IOException ex) { Logger.getLogger(Easy.class.getName()).log(Level.SEVERE, null, ex); } }
Find elsewhere
🌐
Javatpoint
javatpoint.com › java-try-with-resources
Java Try with Resources - javatpoint
Java Try with Resources with examples and topics on functional interface, anonymous class, lambda for list, lambda for comparable, default methods, method reference, java date and time, java nashorn, java optional, stream, filter etc.
🌐
GitHub
github.com › jaychenblue › scout-concordia › issues › 213
QD-7 Use try-with-resources or close this "InputStream" in a "finally" clause. · Issue #213 · jaychenblue/scout-concordia
April 1, 2020 - private void readTheFile(String fileName) throws IOException { Path path = Paths.get(fileName); try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { reader.readLine(); // ... } // .. try (Stream<String> input = Files.lines("input.txt")) { input.forEach(System.out::println); } } private void doSomething() { OutputStream stream = null; try { stream = new FileOutputStream("myfile.txt"); for (String property : propertyList) { // ... } } catch (Exception e) { // ... } finally { stream.close(); } } Exceptions Instances of the following classes are ignored by this rule because close has no effect: java.io.ByteArrayOutputStream java.io.ByteArrayInputStream java.io.CharArrayReader java.io.CharArrayWriter java.io.StringReader java.io.StringWriter Java 7 introduced the try-with-resources statement, which implicitly closes Closeables.
Author   JenYn
🌐
Mkyong
mkyong.com › home › java › java try-with-resources example
Java try-with-resources example - Mkyong.com
November 15, 2022 - Before Java 7, we manually used the try-finally block to ensure that resources were closed. public static void copyFilePlainJava(String from, String to) throws IOException { InputStream inStream = null; OutputStream outStream = null; try { inStream = new FileInputStream(new File(from)); outStream = new FileOutputStream(new File(to)); byte[] buffer = new byte[1024]; // if this throws exception int length; while ((length = inStream.read(buffer)) > 0) { outStream.write(buffer, 0, length); outStream.flush(); } } finally { // if this throws exception if (inStream != null) inStream.close(); // this has a leak if (outStream != null) outStream.close(); } } However, this example might have a resource leak; if the while copy bytes process throws an exception, and the inStream.close() throws an exception, then the outStream has a resource leak and causes a performance issue.
🌐
Initial Commit
initialcommit.com › blog › java-try-resources
Java try-with-resources - Initial Commit
Following is a practical comparison between try/catch/finally and try-with-resources approaches for reading and displaying the content of a file in a file system. ... public void readFileUsingTraditionalTryCatch() { InputStream input = null; try { input = new FileInputStream(new File("test.pdf")); int content; while ((content = input.read()) != -1) { System.out.print((char) content); } } catch (FileNotFoundException fileNotFoundException) { // File is not found fileNotFoundException.printStackTrace(); } catch (IOException ioException) { // error while reading file ioException.printStackTrace(); } finally { // this is to prevent NullPointerException in case // exception occurs while opening file if(input != null) { try { input.close(); } catch (IOException e) { // Handle exception again when closing the input stream e.printStackTrace(); } } } }
🌐
Medium
medium.com › @AlexanderObregon › javas-try-with-resources-statement-explained-6b0ebf84d582
Java’s try-with-resources Statement Explained | Medium
August 18, 2024 - The try-with-resources statement manages the Socket, InputStream, and FileOutputStream, making sure that all resources are closed properly, even if an error occurs during the data transfer.
🌐
Baptiste-wicht
baptiste-wicht.com › posts › 2010 › 08 › java-7-try-with-resources-statement.html
Java 7 : The new try-with-resources statement | Blog blog("Baptiste Wicht");
August 24, 2010 - From the build 105, the compiler and runtime of Java 7 Releases have support for the new form of try : try-with-resources, also called ARM (Automatic Resource Management) blocks. This new statement make working with streams and all kind of closeable resources easier.
🌐
Cleverence
cleverence.com › articles › oracle-documentation › the-try-with-resources-statement-java-tutorial-5938
Java try-with-resources: Complete Guide, Best Practices, and Examples
March 13, 2026 - try-with-resources is a Java language feature (introduced in Java 7 and enhanced in Java 9) that automatically closes resources at the end of a try block. A resource is any object that implements AutoCloseable, such as InputStream, OutputStream, ...
🌐
Java Guides
javaguides.net › 2018 › 08 › the-try-with-resources-statement-with-examples.html
Java try-with-resources Statement
June 21, 2024 - The try-with-resources statement is a try statement that declares one or more resources. A 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 ...