Can I avoid such cumbersome try...catch block - java

Usually, when dealing with Java IO code, here is what I wrote
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
// I put the close code in finally block, to enture the opened
// file stream is always closed even there is exception happened.
if (out != null) {
// Another try catch block, troublesome.
try {
out.close();
} catch (IOException ex) {
}
}
}
As you can see, while I try to close the file stream, I need to deal with another try...catch block.
Look troublesome :(
Is there any way I can avoid? I don't feel comfortable in putting the close code in non-finally block, as exception caused by other codes will make no chance for "close" being called.

It is very important that you close streams in a finally. You can simplify this process with a utility method such as:
public static void closeStream(Closeable closeable) {
if(null != closeable) {
try {
closeable.close();
} catch(IOException ex) {
LOG.warning("Failed to properly close closeable.", ex);
}
}
}
I make it a point of at least logging a stream close failure. The usage then becomes:
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
closeStream(out);
}
In Java 7 I believe that streams will be closed automatically and the need for such blocks should be mostly redundant.

Automatic Resource Management is coming in Java 7 which will automatically provide handling of this. Until then, objects such as OutputStream, InputStream and others implement the Closeable interface since Java 5. I suggest you provide a utility method to safe close these. These methods generally eat exceptions so make sure that you only use them when you want to ignore exceptions (e.g. in finally method). For example:
public class IOUtils {
public static void safeClose(Closeable c) {
try {
if (c != null)
c.close();
} catch (IOException e) {
}
}
}
Note that the close() method can be called multiple times, if it is already closed subsequent calls will have no effect, so also provide a call to close during the normal operation of the try block where an exception will not be ignored. From the Closeable.close documentation:
If the stream is already closed then invoking this method has no effect
So close the output stream in the regular flow of the code and the safeClose method will only perform close if something failed in the try block:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
//...
out.close();
out = null;
} finally {
IOUtils.safeClose(out);
}

Discussion at
Try-catch-finally and then again a try catch
and
Is there a preference for nested try/catch blocks?
basically, the question is whether a close() exception is worth catching.

Project Lombok provides a #Cleanup annotation that removes the need for try catch blocks all together. Here's an example.

I tend to use utility functions for this:
public static void safeClose(OutputStream out) {
try {
out.close();
} catch (Exception e) {
// do nothing
}
}
which changes the code to the slightly more palatable:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
// do stuff
} catch (Exception e) {
// do something
} finally {
safeClose(out);
}
You can't really do much better in Java at least until Java 7 when (hopefully) ARM ("Automatic Resource Management") blocks will help somewhat.

Write a method that looks something like below; call from your finally block...
static void wrappedClose(OutputStream os) {
if (os != null) {
try {
os.close();
}
catch (IOException ex) {
// perhaps log something here?
}
}

Separate your try/catch and try/finally blocks.
try
{
FileOutputStream out = new FileOutputStream("myfile.txt");
try
{
// More and more code goes here...
}
finally
{
out.close();
}
}
catch (Exception e)
{
//handle all exceptions
}
The outer catch will also catch anything thrown by the close.

Related

how emulate "try with resources" for android

try with resources not available on Android,
if you want to target wide range of devices,
so I want emulate something like it, with such semantic:
No exceptions - close, and throw exception if close failed
Has exception - close and ignore close exceptions
Is such code suppose to work as I want or I missed something? And may be possible to simplify it in some way?
final Closeable closebale = ...;
try {
//work with closeable
} catch (IOException e) {
try {
closeable.close();
} catch (IOException e2) {
//log exception
}
closeable = null;
throw e;
} finally {
if (closeable != null) {
//we not catch any exception
closeable.close();
}
}
The historical pattern in Java is:
Closeable foo = null;
try
{
foo = ...;
...
}
finally
{
if (foo != null)
{ foo.close(); }
}
You may put the call to .close() in a try-catch block if you wish to catch and either handle or suppress any exceptions that occur during the attempt to close the resource. I recommend against suppressing exceptions. At a minimum you should log them.

Java Serialization: close streams in try or in a finally block?

I was looking at Java Serialization articles and stumbled a number of times across examples where the streams are closed in the try block instead of in a finally block. Can someone explain to me why is that?
Example:
import java.io.*;
public class DeserializeDemo {
public static void main(String [] args) {
Employee e = null;
try {
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
} catch(IOException i) {
i.printStackTrace();
return;
} catch(ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Source: http://www.tutorialspoint.com/java/java_serialization.htm
The try-with-resources Statement
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.
The following example reads the first line 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:
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).
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:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
Source =>http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
From documentation:
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.
The runtime system always executes the statements within the finally block regardless of what happens within the try block. So it's the perfect place to perform cleanup.
So it means if you have some connection, stream or some other resources opened you have to be sure that they will be closed after your code block will be executed.
To avoid such ugly blocks you can use utility methods:
public void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
// handle block
}
}
}
Since Java 8 (but it is not required) you can provide your own Exception handler with closing resource:
public void close(Closeable closeable, Consumer<? extends Throwable> handler) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
handler.accept(ex);
}
}
}
Also, just for knowledge, there are two cases when finally block is not called. It means that in most cases it will be called.
If you are Java 7 or aboveā€¦
Don't close in finally block
The close method can throw an IOException and FileInputStream/ObjectInputStream can be null. When you use .close in finally, you must check null and try/catch again.
Use "try-with-resources Statement" instead
Using try-with-resources your code looks like this:
try(
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)
) {
e = (Employee) in.readObject();
// in.close();
// fileIn.close();
}
The try-with-resources syntax guarantees the resources implementing AutoCloseable interface will be closed automatically. So you don't need to call a close method on your code.
You should close connection in finally. As finally always going to execute whether it goes in try or catch.
Also we need to close every connection once it created.
try{
// statements
}catch (){
// statements
}
finally {
in.close();
fileIn.close();
}
I was looking at Java Serialization articles and stumbled a number of times across examples where the streams are closed in the try block instead of in a finally block.
Examples that do it that way are poor examples. While closing a stream within a try block will work for simple one-shot examples, doing this in a case where the code might be executed multiple times is liable to lead to resource leaks.
The other Answers to this Question do a good job of explaining the right way(s) to close streams.
Can someone explain to me why is that?
It comes down to poor quality control on the tutorial sites; i.e. inadequate code reviewing.
The accepted answer certainly has a bug.
The close method can throw an IOException too. If this happens when
in.close is called, the exception prevents fileIn.close from getting
called, and the fileIn stream remains open.
It can implemented as below when multiple streams are involved:
} finally {
if ( in != null) {
try { in .close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
if (fileIn != null) {
try {
fileIn.close();
} catch (IOException ex) {
// Again, there is nothing we can do if close fails
}
}
}
Or, take advantage of Closeable Interface
} finally {
closeResource(in);
closeResource(fileIn);
}
Method:
private static void closeResource(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
}
You should close in finally block.
It's a bad habit to close in try block.
try {
e = (Employee) in.readObject(); //Possibility of exception
} catch(IOException i) {
} catch(ClassNotFoundException c) {
} finally {
in.close();
fileIn.close();
}
When someone is writing a code by knowing it will throw an exception,he/she has to close the opened resources
You should always close in a finally block.
However, you can use try with resources.
Here's the link: 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();
}
}

Is attached code safe from open file leak

Assuming Java6, is this code safe from file descriptor leak:
{
InputStream in = fileObject.getReadStream();
// fileObject cleans it's internal state in case it throws exception
try {
// do whatever, possibly throwing exception
} finally {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem
}
}
}
Edit: To make question seem less obvious, to state it other way, is above code equal to this longer code:
{
InputStream in = null;
try {
in = fileObject.getReadStream();
// fileObject cleans it's internal state in case it throws exception
// do whatever, possibly throwing exception
} finally {
if (in != null) {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem
}
}
}
}
That is, does it matter whether a call to a method which returns opened stream or throws exception is immediately before try, or inside the try block?
Yes, fine. Does not even merit an answer. A variant (I less use) is:
InputStream in = null;
try {
in = fileObject.getReadStream();
// do whatever, possibly throwing exception
} finally {
if (in != null) {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem if everything else was ok
}
}
}
I'm a student not very familiar with Java, but I wish I can help you a litltle.
I think that the piece of code can't keep you from the problem of file descriptor leak. Though you have let a try clouse wurround the in.close methord, but that won't help if
the in.close method throws some exceptions.

do I need to surround fileInputStream.close with a try/catch/finally block? How is it done?

I have the following Java Class that does one thing, fires out values from config.properties.
When it comes time to close the fileInputStream, I think I read on Wikipedia that it is good to have it in a finally block. Because it honestly works just fine in try/catch block.
Can you show me correction to get fileInputStream.close() in a finally section?
ConfigProperties.java
package base;
import java.io.FileInputStream;
import java.util.Properties;
public class ConfigProperties {
public FileInputStream fileInputStream;
public String property;
public String getConfigProperties(String strProperty) {
Properties configProperties = new Properties();
try {
fileInputStream = new FileInputStream("resources/config.properties");
configProperties.load(fileInputStream);
property = configProperties.getProperty(strProperty);
System.out.println("getConfigProperties(" + strProperty + ")");
// use a finally block to close your Stream.
// If an exception occurs, do you want the application to shut down?
} catch (Exception ex) {
// TODO
System.out.println("Exception: " + ex);
}
finally {
fileInputStream.close();
}
return property;
}
}
Is the solution only to do as Eclipse suggests and do this in the finally block?
finally {
try {
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Yes, that is the common pre-Java 7 solution. However, with the introduction of Java 7, there are now try-with-resource statements which will automatically close any declared resources when the try block exits:
try (FileInputStream fileIn = ...) {
// do something
} // fileIn is closed
catch (IOException e) {
//handle exception
}
The standard approach is:
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(...);
// do something with the inputstream
} catch (IOException e) {
// handle an exception
} finally { // finally blocks are guaranteed to be executed
// close() can throw an IOException too, so we got to wrap that too
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
// handle an exception, or often we just ignore it
}
}
Because FileInputStream.close() throws an IOException, and the finally{} block doesn't catch exceptions. So you need to either catch it or declare it in order to compile. Eclipse's suggestion is fine; catch the IOException inside the finally{} block.
It's a good habit to close streams because what it does in background it's called buffering, meaning that it does not free the internal buffer and does not free the file descriptor.

How do I open, write and save a file while avoiding errors?

I need to erase a file in my program. My solution was to have an erase() method that would do that like so:
public static void erase(String string) {
FileWriter fw = null;
try {
fw = new FileWriter(string);
fw.write(new String());
} catch (IOException ie) {
e.printStackTrace();
} finally {
fw.flush();
fw.close();
}
}
Several problems here:
If the fw does not properly initialize (for whatever reason, missing file, invalid persmissions, etc) then when I try to close it in the finally block, there is a NullPointerException.
If I don't have the finally block, then I might be throwing a NullPointerException for the reason above.
If I close the file inside the try block, then I might leak the resource if the file properly opens, but doesn't properly write.
What other problems am I overlooking and how can I harden this method?
You can just wrap the finally functionality in an if-statement:
if(fw != null){
fw.close();
}
This will ensure that if the file was ever opened, then it will be closed. If it wasn't opened in the first place, then it won't do anything, which is what you want.
Also, I'm not sure if it's just like that for posting, but it's generally not advisable to just print a stacktrace in a catch block and continue ("swallowing" the exception). You really should let the exception get thrown because this could hide bugs and make tracking them down very hard.
EDIT: See comment below.
To the best of my knowledge, this is the correct idiomatic way to write your code:
FileWriter fw = new FileWriter(string);
try {
fw.write(new String());
fw.flush();
} catch (IOException ie) {
ie.printStackTrace();
} finally {
fw.close();
}
Explanation:
If new FileWriter() throws an exception, then we don't need to clean up anything. The method exits without executing the finally.
We should put fw.flush() in the try, not in the finally. There are two reasons: If the write failed, then we shouldn't bother flushing. Also, if you put the flush() in finally and it throws an exception, then the close() will be skipped.
Include the flush() in your main block and have only the close() in the catch. Then check for null before closing:
finally {
if(fw!=null) { fw.close(); }
}
With the flush in the main block, you can also try/catch the close and log or ignore any error:
finally {
if(fw!=null) {
try { fw.close(); } catch(Throwable thr) { log.printError("Close failed: "+thr); thr.printStackTrace(); }
}
}
or (not generally recommended):
finally {
try { fw.close(); } catch(Throwable thr) {;}
}
EDIT
The best general Java idiom for handling I/O, IMO, is:
FileWriter fw=null;
try {
fw=new FileWriter(string);
fw.write(new String());
fw.close();
fw=null;
}
catch(IOException ie) {
// do something real here to handle the exception, or don't catch it at all.
}
finally {
if(fw!=null) {
try { fw.close(); } catch(Throwable thr) { thr.printStackTrace(); } // now we're really out of options
}
}
This has the important effect of allowing the catch to catch and handle an exception thrown by close() itself. (The catch clause should only be present if you can handle the exception in some way; do NOT catch and ignore, and generally you should not simply catch and trace.)

Categories

Resources