try-with-resources details [duplicate] - java

This question already has answers here:
Try With Resources vs Try-Catch [duplicate]
(5 answers)
Closed 7 years ago.
Working with objects we use 3 basic steps:
Declaration
Instantiation
Initialization
And my question is about what steps must be done in () part of try-with in order auto close on resource to be made.
Example 1 - will FileReader object be auto closed in this code:
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
//some code;
}
Example 2 - will the buf2 be auto closed in this code:
private static BufferedReader buf1;
public static void main(String[] args) throws IOException {
//some code
try (BufferedReader buf2 = buf1)
{
}
}
P.S. Someone supposes that this question is duplicate of Try With Resources vs Try-Catch . It is not. That question is about difference between try-catch and try-with-resources. My question is about details of try-with.

Whenever language related details are needed, the most complete reference is the Java Language Specification (just Google it). For the try-with-resources statement, you can read section 14.20.3 which states that the following:
try ({VariableModifier} R Identifier = Expression ...)
Block
is translated to
{
final {VariableModifierNoFinal} R Identifier = Expression;
Throwable #primaryExc = null;
try ResourceSpecification_tail
Block catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
}
In your first example, the resource R is BufferedReader, the Identifier is br and the Expression is new BufferedReader(new FileReader(filePath)). It follows that only the BufferedReader is closed in the implicit finally block. The finally block will not call close on the FileReader because it is not part of the resource declaration itself. However, it happens that the implementation of BufferedReader.close() internally calls the close method of the wrapped FileReader. So the answer to the first question is yes simply because the wrapper object closed it (following the common wisdom that a resource should release any wrapped resource when being itself released), not because of the try-with-resources.
In the second example:
private static BufferedReader buf1;
public static void main(String[] args) throws IOException {
//some code
try (BufferedReader buf2 = buf1)
{
}
}
the answer depends on the some code. Here buf2 and buf1 both refer to the same object in memory. If this "some code" initializes buf1 to some object, then this object will be closed since buf2 also refers to it. If not and buf1 is null (and therefore buf2 is null), then nothing will be closed because of the null check in the implicit finally shown above.

FileReader will be closed. But that is not because it is in the try statement. It is because when BufferedReader is closed, it calls close() on FileReader as well. For a counter example, I have a class called X that implements AutoCloseable. And that class needs a Foo object in its constructor. So I write:
try (X x = new X(new Foo())) {
}
Will Foo be closed? It doesn't even implement AutoCloseable!
I wrote the following to test this:
BufferedReader buf1 = null;
try (BufferedReader buf2 = buf1) {
}
And it worked perfectly fine, no exceptions! My guess is that at the end of the try statement, it checks whether the object is null. If it is not, then close it. So in this case, because buf2 is null, it can't be closed.

Related

How to use try-with-resources in nested function in java? [duplicate]

This question already has answers here:
What's the purpose of try-with-resources statements?
(7 answers)
Closed 8 months ago.
I noticed that if I don't call myBufferedWriter.close(), my content will not appear in the target file. What if the program ends accidentally before reaching myBufferedWriter.close()? How to avoid losing data that are already in the buffer but not written to the file yet?
Edit:
I have found the simple use case of try-with-resources, but my code is like the following
public class myClass{
Map<String, BufferedWriter> writerMap = new HashMap<>();
public void write(···){
//call this.create() here
···
//normally, the writer will close here
}
public void create(···){
//BufferedWriter is created here, and saved into writerMap
···
}
}
Where is the best place to use the try-with-resources statement?
You can handle it with a try - catch - finally sentence.
Something like:
try {
// Do things
} catch (Exception e) {
e.printStackTrace();
} finally {
if (myBufferedWriter != null) {
try {
myBufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your best bet is The try-with-resources Statement.
The try-with-resources statement ensures that each resource is closed at the end of the statement.
[...] the try-with-resources statement contains [...] declarations that are separated by a semicolon[...]. When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the [...] objects are automatically called in this order. Note that the close methods of resources are called in the opposite order of their creation.
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with
// try-with-resources statement
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}

do i need call close() on every new inputstream?

here is the code.
public static void main(String[] args) throws IOException {
FileInputStream fis = null;
fis = new FileInputStream(new File("D:\\za180s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za185s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za186s.ser"));
// do something
fis = new FileInputStream(new File("D:\\za187s.ser"));
// do something
fis.close();
}
the problem is : need i call fis.close() method after every "do something" or i just call fis.close() once after all.
ignore whether the close() position in finally and the code need try catch or not.
thx all.
Yes, you need to call close on each individual InputStream. The problem with your code is that you're reassigning the variable fis each time you create a new stream. In other words: fis no longer points to the old InputStream, so calling close will not close the previous stream.
For more information, check https://stackoverflow.com/a/40523/8819761
What you could also do is use Java 7's try-with-resources syntax, which will auto-close the stream once you exit the try block:
try (InputStream fis = new FileInputSteam(yourFile)) {
// Do something
}
try (InputStream fis = new FileInputSteam(yourFile)) {
// Do something else
}
You have to do close everytime you finish working with InputStream.
In java, if you assign
fis = new FileInputStream(new File("D:\\za180s.ser"));
fis will point to the new object so when you call fis.close() the old streams are not affected. And there is no way to close it.
You need to call close method every time but don't worry now.From Java SE 7 you can use try-with-resources. As per Java-Oracle Doc,
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 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.
Please have a look on example.
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the 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).
For more details, Please have a look on Oracle-Java doc for try-with-resources.
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

finally { if (inputStream != null) { inputStream.close();

I don't know how to understand this:
{
if (inputStream **!= null**) {
inputStream.close();
from that example:
public class CopyLines {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}}
inputStream is beeing closed when there is any data provided???
It means that whenever the try block is completed (successfully or not) it will try to close the streams (inputStream and outputStream) in the finally block but as the try block could fail while creating the instance of BufferedReader or PrintWriter, you need to check first if it is not null otherwise you will get a NPE.
You can consider using try-with-resouces statement to avoid having to check if null and calling close() explicitly such that it would simplify your code a lot.
try (BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt")) {
// your code here
}
If you're asking why this code is in finally block, then,
This is simply to ensure that the inputStream and outputStream will always be closed, no matter whether the code above encounters or doesn't encounters an exception.
How is it different.
The difference is during any exception. If any exception occurs, then instead of simply returning, it will ensure that both the streams are closed before returning the exception to the method that called this method.
bacause java's finally block is always executed, unless:
System.exit is called
or JVM crashes
This is a common practice to close stream, database, or any other similar connections in finally blocks. This ensures that the connections are always closed. Because if they aren't in finally block, and system is continuously encountering some or the other Excpetion then it will eventually run out of connections.
That's just to avoid null pointer exception. The functions are called only when object is not null.
In simple words, close function is only called when the objects are not null else if you call close() on object with null value, you will come across null pointer exception.
Interesting thing is the usage of finally, which is always called whether there is any exception or not.
When the execution reaches the finally block, it is first checked inputstream and outputstream are null or not then both the streams are closed to free the resources.
Please refer the link to check about try with finally : https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2

What is Round brackets / parentheses () in try catch in Java

As per as my knowledge we use try catch as follows:
try {
//Some code that may generate exception
}
catch(Exception ex) {
}
//handle exception
finally {
//close any open resources etc.
}
But in a code I found following
try(
ByteArrayOutputStream byteArrayStreamResponse = new ByteArrayOutputStream();
HSLFSlideShow pptSlideShow = new HSLFSlideShow(
new HSLFSlideShowImpl(
Thread.currentThread().getContextClassLoader()
.getResourceAsStream(Constants.PPT_TEMPLATE_FILE_NAME)
));
){
}
catch (Exception ex) {
//handel exception
}
finally {
//close any open resource
}
I am not able to understand why this parentheses () just after try.
What is the usage of it? Is it new in Java 1.7? What kind of syntax I can write there?
Please also refer me some API documents.
It is try with Resources syntax which is new in java 1.7. It is used to declare all resources which can be closed. Here is the link to official documentation.
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the 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).

Java resource closing

I'm writing an app that connect to a website and read one line from it. I do it like this:
try{
URLConnection connection = new URL("www.example.com").openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = rd.readLine();
rd.close();
}catch (Exception e) {
//exception handling
}
Is it good? I mean, I close the BufferedReader in the last line, but I do not close the InputStreamReader. Should I create a standalone InputStreamReader from the connection.getInputStream, and a BufferedReader from the standalone InputStreamReader, than close all the two readers?
I think it will be better to place the closing methods in the finally block like this:
InputStreamReader isr = null;
BufferedReader br = null;
try{
URLConnection connection = new URL("www.example.com").openConnection();
isr = new InputStreamReader(connection.getInputStream());
br = new BufferedReader(isr);
String response = br.readLine();
}catch (Exception e) {
//exception handling
}finally{
br.close();
isr.close();
}
But it is ugly, because the closing methods can throw exception, so I have to handle or throw it.
Which solution is better? Or what would be the best solution?
The general idiom for resource acquisition and release in Java is:
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
Note:
try should immediately follow the acquire. This means you can't wrap it in the decorator and maintain safety (and removing spaces or putting things on one line doesn't help:).
One release per finally, otherwise it wont be exception safe.
Avoid null, use final. Otherwise you'll have messy code and potential for NPEs.
Generally there is no need to close the decorator unless it has a further resource associated with it. However, you will generally need to flush outputs, but avoid that in the exception case.
The exception should either be passed through to the caller, or caught from a surrounding try block (Java leads you astray here).
ou can abstract this nonsense with the Execute Around idiom, so you don't have to repeat yourself (just write a lot of boilerplate).
Closing the BufferedReader is enough - this closes the underlying reader too.
Yishai posted a nice pattern for closing the streams (closing might throw another exception).
Is it good? I mean, I close the BufferedReader in the last line, but I do not close the InputStreamReader.
Apart from the fact that it should be done in the finally (so that the close is ensured, even in case of an exception), it's fine. The Java IO classes uses the decorator pattern. The close will be delegated to the underlying streams.
But it is ugly, because the closing methods can throw exception, so I have to handle or throw it.
When the close throws an exception, it often just means that the other side has been closed or deleted, which is completely out of your control. You can at highest log or ignore it. In a simple application I would just ignore it. In a mission critical application I would log it, just to be sure.
In a nut, your code can be rewritten as:
BufferedReader br = null;
try {
URLConnection connection = new URL("www.example.com").openConnection();
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = br.readLine();
}catch (Exception e) {
//exception handling
}finally{
if (br != null) try { br.close(); } catch (IOException ignore) {}
}
In Java 7 there will be automatic resource handling which would made your code as concise as:
try (BufferedReader br = new InputStreamReader(new URL("www.example.com").openStream())) {
String response = br.readLine();
} catch (Exception e) {
//exception handling
}
See also:
Java IO tutorial
C# "using" keyword in Java
How to use URLConnection
BufferedReader br = null;
You are declaring a variable without assigning it (null doesn't count - it is a useless assignment in this case). This is a code "smell" in Java (ref Effective Java; Code Complete for more on variable declaration).
}finally{
br.close();
isr.close();
}
First, you only need to close the top-most stream decorator (br will close isr). Secondly, if br.close() threw an exception, isr.close() would not be called, so this is not sound code. Under certain exception conditions, your code will hide the originating exception with a NullPointerException.
isr = new InputStreamReader(connection.getInputStream());
If the (admittedly unlikely) event that the InputStreamReader constructor threw any kind of runtime exception, the stream from the connection would not be closed.
Make use of the Closeable interface to reduce redundancy.
Here is how I would write your code:
URLConnection connection = new URL("www.example.com").openConnection();
InputStream in = connection.getInputStream();
Closeable resource = in;
try {
InputStreamReader isr = new InputStreamReader(in);
resource = isr;
BufferedReader br = new BufferedReader(isr);
resource = br;
String response = br.readLine();
} finally {
resource.close();
}
Note that:
no matter what kind of exception is thrown (runtime or checked) or where, the code does not leak stream resources
there is no catch block; exceptions should be passed up to where the code can make a sensible decision about error handling; if this method was the right place, you'd surround all of the above with try/catch
A while back, I spent some time thinking about how to avoid leaking resources/data when things go wrong.
I think it will be better to place the
closing methods in the finally block
Yes, always. Because an exception might occur and resources aren't released/closed properly.
You only need to close the most outer reader because it will be responsible for closing any enclosing readers.
Yes, it's ugly... for now. I think there are plans for an automatic resource management in Java.
I'd use apache commons IO for this, as others have suggested, mainly IOUtils.toString(InputStream) and IOUtils.closeQuietly(InputStream):
public String readFromUrl(final String url) {
InputStream stream = null; // keep this for finally block
try {
stream = new URL(url).openConnection().getInputStream(); // don't keep unused locals
return IOUtils.toString(stream);
} catch (final IOException e) {
// handle IO errors here (probably not like this)
throw new IllegalStateException("Can't read URL " + url, e);
} finally {
// close the stream here, if it's null, it will be ignored
IOUtils.closeQuietly(stream);
}
}
You don't need multiple close statements for any of the nested streams and readers in java.io. It's very rare to need to close more than one thing in a single finally - most of the constructors can throw an exception, so you would be trying to close things you haven't created yet.
If you want to close the stream whether or not the read succeeds, then you need to put in into a finally.
Don't assign null to variables and then compare them to see whether something happened earlier; instead structure your program so the path where you close the stream can only be reached if the exception is not thrown. Apart from the variables used to iterate in for loops, variables should not need to change value - I tend to mark everything final unless there is a requirement to do otherwise. Having flags around your program to tell you how you got to the code currently being executed, and then changing behaviour based on those flags, is very much a procedural (not even structured) style of programming.
How you nest the try/catch/finally blocks depends on whether you want to handle the exceptions thrown by the different stages differently.
private static final String questionUrl = "http://stackoverflow.com/questions/3044510/";
public static void main ( String...args )
{
try {
final URLConnection connection = new URL ( args.length > 0 ? args[0] : questionUrl ).openConnection();
final BufferedReader br = new BufferedReader ( new InputStreamReader (
connection.getInputStream(), getEncoding ( connection ) ) );
try {
final String response = br.readLine();
System.out.println ( response );
} catch ( IOException e ) {
// exception handling for reading from reader
} finally {
// br is final and cannot be null. no need to check
br.close();
}
} catch ( UnsupportedEncodingException uee ) {
// exception handling for unsupported character encoding
} catch ( IOException e ) {
// exception handling for connecting and opening reader
// or for closing reader
}
}
getEncoding needs to inspect the results of the connection's getContentEncoding() and getContentType() to determine the encoding of the web page; your code just uses the platform's default encoding, which may well be wrong.
Your example though is unusual in structured terms, since it is very procedural; normally you would separate the printing and the retrieving in a larger system, and allow the client code to handle any exception (or sometimes catch and create a custom exception):
public static void main ( String...args )
{
final GetOneLine getOneLine = new GetOneLine();
try {
final String value = getOneLine.retrieve ( new URL ( args.length > 0 ? args[0] : questionUrl ) );
System.out.println ( value );
} catch ( IOException e ) {
// exception handling for retrieving one line of text
}
}
public String retrieve ( URL url ) throws IOException
{
final URLConnection connection = url.openConnection();
final InputStream in = connection.getInputStream();
try {
final BufferedReader br = new BufferedReader ( new InputStreamReader (
in, getEncoding ( connection ) ) );
try {
return br.readLine();
} finally {
br.close();
}
} finally {
in.close();
}
}
As McDowell pointed out, you may need to close the input stream if new InputStreamReader throws.
In scope of Java 8 I would use alike:
try(Resource resource = acquire()) {
use(resource);
reuse(resource);
}

Categories