This question already has answers here:
Java io ugly try-finally block
(12 answers)
Closed 8 years ago.
This is a code style question. I notice much example code including some examples from Oracle ensure that a stream is closed in the following manner:
InputStream in = null;
try {
in = acquireStream();
...
} finally {
if (in != null) in.close();
}
Note the initialization to null and check for null in the finally block.
I tend to write code like this:
InputStream in = acquireStream();
try {
...
} finally {
in.close();
}
Are there advantages or disadvantages to either approach? I like my style because I don't need the null check. Also I like to avoid null when possible. But since the Oracle style is so common in online examples, I'm wondering if mine has some hidden error.
I ask the same question for InputStream, OutputStream, java.sql.Connection, java.sql.PreparedStatement, etc. I tend to acquired the resource outside the try block and then close it in finally without a null check. Is there anything I am missing other than stylistic differences?
Thanks.
Since Java 7 there is a much nicer way to write try-finally block in regards to Closeable resources.
Now you can create your resources in parenthesis after the try keyword, like this:
try (init resources) {
...
}
And they will be closed automcatically after the block of code is finished. There is no need to close the streams in finally block.
An example:
try (
ZipFile zf = new ZipFile(zipFileName);
BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset);
) {
// Enumerate each entry
for (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());
}
}
And after the for loop is done, the resources will be closed!
The answer is, no, there is no hidden error with doing it your way. It is purely a style thing.
I typically never have a try catch finally block, only try catch blocks and try finally blocks.
They tend to end up looking like this:
try {
InputStream in = acquireStream();
try {
...
} finally {
in.close();
}
} catch (IOException e) {
... handle exception
}
There is no reason to put acquireStream() in the try finally block. If in is never assigned to a valid stream, you can never close it. An explicit null check is totally unnecessary. Additionally, it is rare that you want to handle an exception on the close() differently than an exception in the main processing block.
Typically what you have is try, catch, finally. In that case, it's advantageous to use the standard SUN approach because you can capture any errors that occured in acquireStream() inside of the try, catch.
I would use
InputStream in = null;
try {
in = acquireStream();
...
} finally {
if (in != null) in.close();
}
if aquireStream() throws any checked exception and I am planning to handle it.
Else, I will use this
InputStream in = acquireStream();
try {
...
} finally {
in.close();
}
on NPE:
I would rather let NPE to propagate and not handle any run-time exception.
I think it's safer to acquire the stream within the try block.
There's another option for closing - instead of checking for null you can do the following:
finally {
IOUtils.closeQuietly(in);
}
This does require Apache Commons-IO to do this, but it will do the null check for you. It's also a nice way stylistically to do this.
If your acquireStream() returned null, You will get NPE when you will try to close your stream in finally block and it will be uncaught.
I favor the first. Some I/O operators require they are inside a try/catch for
some condition or other. Also, operations can always return null unexpectedly,
even though that is not in the manual.
I usually do this:
InputStream in = null;
try {
in = acquire();
...
} finally {
if( in != null ) try {
in.close();
} catch( IOException ioe ) {
// ignore exception while closing
}
}
While closing the resource, an exception may be thrown, in which case you'll need an extra try/catch , but most of the times it's ok for me to ignore it ( I'm closing it after all ) but this is the only place where I use an if without braces.
I saw this from Huckster code long ago.
Related
This question already has answers here:
What's the purpose of try-with-resources statements?
(7 answers)
Closed 2 years ago.
I have been looking at code and I have seen try with resources. I have used the standard try-catch statement before and it looks like they do the same thing. So my question is Try With Resources vs Try-Catch what are the differences between those, and which is better.
Here is a try with resources :
objects jar = new objects("brand");
objects can= new objects("brand");
try (FileOutputStream outStream = new FileOutputStream("people.bin")){
ObjectOutputStream stream = new ObjectOutputStream(outStream);
stream.writeObject(jar);
stream.writeObject(can);
stream.close();
} catch(FileNotFoundException e) {
System.out.println("sorry it didn't work out");
} catch(IOException f) {
System.out.println("sorry it didn't work out");
}
The main point of try-with-resources is to make sure resources are closed reliably without possibly losing information.
When you don't use try-with-resources there's a potential pitfall called exception-masking. When code in a try block throws an exception, and the close method in the finally also throws an exception, the exception thrown by the try block gets lost and the exception thrown in the finally gets propagated. This is usually unfortunate, since the exception thrown on close is something unhelpful while the informative one is the one thrown from within the try block. (So instead of seeing the SQLException that tells you which referential integrity constraint was violated, you're shown something like BrokenPipeException where closing the resource failed.)
This exception-masking is an annoying problem that try-with-resources prevents from happening.
As part of making sure exception-masking wouldn't lose important exception information, when try-with-resources was developed they had to decide what to do with the exceptions thrown from the close method.
With try-with-resources, if the try block throws an exception and the close method also throws an exception, then the exception from the close block gets tacked on to the original exception:
... there are situations where two independent exceptions can be thrown in sibling code blocks, in particular in the try block of a try-with-resources statement and the compiler-generated finally block which closes the resource. In these situations, only one of the thrown exceptions can be propagated. In the try-with-resources statement, when there are two such exceptions, the exception originating from the try block is propagated and the exception from the finally block is added to the list of exceptions suppressed by the exception from the try block. As an exception unwinds the stack, it can accumulate multiple suppressed exceptions.
On the other hand if your code completes normally but the resource you're using throws an exception on close, that exception (which would get suppressed if the code in the try block threw anything) gets thrown. That means that if you have some JDBC code where a ResultSet or PreparedStatement is closed by try-with-resources, an exception resulting from some infrastructure glitch when a JDBC object gets closed can be thrown and can rollback an operation that otherwise would have completed successfully.
Without try-with-resources whether the close method exception gets thrown is up to the application code. If it gets thrown in a finally block when the try block throws an exception, the exception from the finally block will mask the other exception. But the developer has the option of catching the exception thrown on close and not propagating it.
You missed something, the finally block. The try-with-resouces will make it something like,
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream("people.bin");
ObjectOutputStream stream = new ObjectOutputStream(outStream);
stream.writeObject(jar);
stream.writeObject(can);
stream.close();
} catch(FileNotFoundException e) {
System.out.println("sorry it didn't work out");
} catch(IOException f) {
System.out.println("sorry it didn't work out");
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (Exception e) {
}
}
}
Which means you really wanted something like (never swallow exceptions),
try (FileOutputStream outStream = new FileOutputStream("people.bin");
ObjectOutputStream stream = new ObjectOutputStream(outStream);) {
stream.writeObject(jar);
stream.writeObject(can);
// stream.close(); // <-- closed by try-with-resources.
} catch(FileNotFoundException e) {
System.out.println("sorry it didn't work out");
e.printStackTrace();
} catch(IOException f) {
System.out.println("sorry it didn't work out");
e.printStackTrace();
}
The only difference is that try-resource is adding automatically resource.close();
as you would do in finally block
Any object (either the class or their superclass) that implements java.lang.AutoCloseable or java.io.Closeable
can only be used in try-with-resource clause.
AutoClosable interface is the parent interface and Closable interface extends the AutoClosable interface.AutoClosable interface has method close which throws Exception while Closable interface has method that throws IOException.
We can also have catch and finally block followed by try-with-resource like ordinary try, catch and finally, but catch and finally block only get executed once the resource declared inside the try-with-resource clause is closed.
Succinctly it is syntactic sugar to support the AutoClosable interface and call the close() method for you for any outcome.
so I have a bit of code here and I'm not sure entirely how it would react in the event that the reader.close() method throws an exception.
public void someMethod(String s) throws IOException{
BufferedReader reader = Files.newBufferedReader(filePath,cs);
listRWLock.readLock().lock();
try{
//miscellaneous code involving reading
}finally{
reader.close()
listRWLock.readLock().unlock()
}
}
ListRWLock is a ReentrantReadWriteLock. In the event that the reader.close() method throws an exception, would the statement after it fail to execute? I've tried searching for the topic, and while I've gotten something about finally executing in the event of return statements, I haven't managed to find details on what happens if an exception is thrown within the finally block.
Thanks in advance.
Basically, finally clauses are there to ensure proper release of a resource. However, if an exception is thrown inside the finally block, that guarantee goes away.
An issue for which there's no really neat solution is that code in the finally block could itself throw an exception. In this case, the exception in the finally block would be thrown from the exception instead of any exception occurring inside the try block. Since code in the finally block is intended to be "cleanup" code, we could decide to treat exceptions occurring there as secondary, and to put an excplicit catch:
public int readNumber(File f) throws IOException, NumberFormatException {
BufferedReader br = new BufferedReader(new
InputStreamReader(new FileInputStream(f), "ASCII"));
try {
return Integer.parseInt(br.readLine());
} finally {
try { br.close(); } catch (IOException e) {
// possibly log e
}
}
}
Some other things to note about finally blocks:
The same 'overriding' problem that we mentioned with exceptions
occurs when returning a value from a finally block: this would
override any return value that the code in the try block wanted to
return. In practice, returning a value from a finally clause is rare
and not recommended.
Actually exiting the program (either by calling System.exit() or by
causing a fatal error that causes the process to abort: sometimes
referred to informally as a "hotspot" or "Dr Watson" in Windows)
will prevent your finally block from being executed!
There's nothing to stop us nesting try/catch/finally blocks (for
example, putting a try/finally block inside a try/catch block, or
vice versa), and it's not such an uncommon thing to do.
You can do something like this:
try{
//miscellaneous code involving reading
}finally{
handlePossibleException(reader);
listRWLock.readLock().unlock()
}
handlePossibleException(BufferedReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch( Exception e ) {
log.e( "reader.close() Exception: ", e );
}
}
You should test this,
but if try throws IO Exception, then your reader wont close.
Maybe have
catch(IOException ex){
reader.close()
An exception can happen anywhere in your code, including finally block, so you have to catch it as anywhere else in your code. Check the following post to get some ideas about the ways you can handle such situation:
throws Exception in finally blocks
Basically I am not really sure what is the correct usage of the finally keyword, I only know the textual definition: Guarantees a code will be executed cause sometimes it doesn't. So I was hoping I could get some directions on this particular code:
Also if the try-catch block to call InputStream#close() is unnecesary
try {
inputStream = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
responseText = sb.toString();
} catch(IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
You can also use a try-with-resources.
Like so:
try (YourResource resource) {
//Todo...
} catch(YourSpecificException ex) {
//Todo...
}
Your resource declared between parantheses will be automatically closed upon exiting the construction.
You can even declare multiple resources in one go, separate them with a semi-colon. It's all in the above link, really.
The finally block will always be executed whether the exception has arise from try block or not.So finally block is used as post activity.In the code you are using to close the stream.
the finally block ensures that no matter what happens during your try( success or exception), it will always run. This is normally used when cleaning up resources, like InputStream or a Socket
The try with resource paradigm cleans this up, but automatically closing things that are Closeable
try( InputStream inputStream = entity.getContent() )
{
}catch(Exception e)
{
}//declared resource in try automatically closed
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
When try block is executing any exception that occurs will transfer the execution to the catch block then to finally block however if no exception happens in the try the execution of the code will continue after the try to the finally block, here in your code you are trying to use IO resource, which might throws an IO exception if it cannot be occupied by the process then no reference will be assigned to inputStream a finally block must be found to close the IO connection at any case if the resource was occupied or if it is null then nothing, remember finally will always be executed at any case, it is best for closing connection to databases and other resources to release memory too sometimes.
The times I've used finally are generally...
resource handling (IO, DB connections, sockets)
Concurrency (lock releasing, guaranteed counter changes)
finalization (try { } finally { super.finalize(); })
record keeping of states
try {
// Here the guarded area starts
// Here the guarded area ends
} catch {
// This block is executed when an exception occurs inside the guarded area
} finally {
// This block is executed always before leaving try - catch - finally block
// If there is an exception, then first catch block is executed and then finally
}
The code inside finally block you have is a commonly used structure for closing streams. If a stream was created inside guarded area (inputStream != null), then finally block will close it. If there was an exception before inputStream was created, then finally block is executed, but because inputStream == null, the code inside if statement does not execute.
Just a simple question. Given this code:
try {
// operation on inputstream "is"
} finally {
try {
is.close();
} catch (IOException ioe) {
//if ioe is thrown, will the handle opened by 'is' be closed?
}
}
If the close() throws, is the file handle still around (and leaked), or will it have been closed?
Not reliably so. If is.close() throws, is might not be marked closed. In any case, there is nothing you can do about it. You don't know the internals of is. The Java 7 equivalent simply hides the problem.
try (InputStream is = Files.newInputStream(...)) {
// Stuff with is.
} catch (IOException is) {
... // Handles exceptions from the try block.
} // No finally. Handled by try-with-reources
If the auto-close throws, the exception is a suppressed exception, and you'll never know if or when the file handle is reclaimed.
This question already has answers here:
Is it necessary to close each nested OutputStream and Writer separately?
(7 answers)
Closed 6 years ago.
Note: This question and most of its answers date to before the release of Java 7. Java 7 provides Automatic Resource Management functionality for doing this easilly. If you are using Java 7 or later you should advance to the answer of Ross Johnson.
What is considered the best, most comprehensive way to close nested streams in Java? For example, consider the setup:
FileOutputStream fos = new FileOutputStream(...)
BufferedOS bos = new BufferedOS(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
I understand the close operation needs to be insured (probably by using a finally clause). What I wonder about is, is it necessary to explicitly make sure the nested streams are closed, or is it enough to just make sure to close the outer stream (oos)?
One thing I notice, at least dealing with this specific example, is that the inner streams only seem to throw FileNotFoundExceptions. Which would seem to imply that there's not technically a need to worry about closing them if they fail.
Here's what a colleague wrote:
Technically, if it were implemented right, closing the outermost
stream (oos) should be enough. But the implementation seems flawed.
Example:
BufferedOutputStream inherits close() from FilterOutputStream, which defines it as:
155 public void close() throws IOException {
156 try {
157 flush();
158 } catch (IOException ignored) {
159 }
160 out.close();
161 }
However, if flush() throws a runtime exception for some reason, then
out.close() will never be called. So it seems "safest" (but ugly) to
mostly worry about closing FOS, which is keeping the file open.
What is considered to be the hands-down best, when-you-absolutely-need-to-be-sure, approach to closing nested streams?
And are there any official Java/Sun docs that deal with this in fine detail?
When closing chained streams, you only need to close the outermost stream. Any errors will be propagated up the chain and be caught.
Refer to Java I/O Streams for details.
To address the issue
However, if flush() throws a runtime exception for some reason, then out.close() will never be called.
This isn't right. After you catch and ignore that exception, execution will pick back up after the catch block and the out.close() statement will be executed.
Your colleague makes a good point about the RuntimeException. If you absolutely need the stream to be closed, you can always try to close each one individually, from the outside in, stopping at the first exception.
In the Java 7 era, try-with-resources is certainly the way to go. As mentioned in several previous answers, the close request propagates from the outermost stream to the innermost stream. So a single close is all that is required.
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) {
// do something with ois
}
There is however a problem with this pattern. The try-with-resources is not aware of the inner FileInputStream, so if the ObjectInputStream constructor throws an exception, the FileInputStream is never closed (until the garbage collector gets to it). The solution is...
try (FileInputStream fis = new FileInputStream(f); ObjectInputStream ois = new ObjectInputStream(fis)) {
// do something with ois
}
This is not as elegant, but is more robust. Whether this is actually a problem will depend on what exceptions can be thrown during construction of the outer object(s). ObjectInputStream can throw IOException which may well get handled by an application without terminating. Many stream classes only throw unchecked exceptions, which may well result in termination of the application.
It is a good practice to use Apache Commons to handle IO related objects.
In the finally clause use IOUtils
IOUtils.closeQuietly(bWriter);
IOUtils.closeQuietly(oWritter);
Code snippet below.
BufferedWriter bWriter = null;
OutputStreamWriter oWritter = null;
try {
oWritter = new OutputStreamWriter( httpConnection.getOutputStream(), "utf-8" );
bWriter = new BufferedWriter( oWritter );
bWriter.write( xml );
}
finally {
IOUtils.closeQuietly(bWriter);
IOUtils.closeQuietly(oWritter);
}
I usually do the following. First, define a template-method based class to deal with the try/catch mess
import java.io.Closeable;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public abstract class AutoFileCloser {
// the core action code that the implementer wants to run
protected abstract void doWork() throws Throwable;
// track a list of closeable thingies to close when finished
private List<Closeable> closeables_ = new LinkedList<Closeable>();
// give the implementer a way to track things to close
// assumes this is called in order for nested closeables,
// inner-most to outer-most
protected final <T extends Closeable> T autoClose(T closeable) {
closeables_.add(0, closeable);
return closeable;
}
public AutoFileCloser() {
// a variable to track a "meaningful" exception, in case
// a close() throws an exception
Throwable pending = null;
try {
doWork(); // do the real work
} catch (Throwable throwable) {
pending = throwable;
} finally {
// close the watched streams
for (Closeable closeable : closeables_) {
if (closeable != null) {
try {
closeable.close();
} catch (Throwable throwable) {
if (pending == null) {
pending = throwable;
}
}
}
}
// if we had a pending exception, rethrow it
// this is necessary b/c the close can throw an
// exception, which would remove the pending
// status of any exception thrown in the try block
if (pending != null) {
if (pending instanceof RuntimeException) {
throw (RuntimeException) pending;
} else {
throw new RuntimeException(pending);
}
}
}
}
}
Note the "pending" exception -- this takes care of the case where an exception thrown during close would mask an exception we might really care about.
The finally tries to close from the outside of any decorated stream first, so if you had a BufferedWriter wrapping a FileWriter, we try to close the BuffereredWriter first, and if that fails, still try to close the FileWriter itself. (Note that the definition of Closeable calls for close() to ignore the call if the stream is already closed)
You can use the above class as follows:
try {
// ...
new AutoFileCloser() {
#Override protected void doWork() throws Throwable {
// declare variables for the readers and "watch" them
FileReader fileReader =
autoClose(fileReader = new FileReader("somefile"));
BufferedReader bufferedReader =
autoClose(bufferedReader = new BufferedReader(fileReader));
// ... do something with bufferedReader
// if you need more than one reader or writer
FileWriter fileWriter =
autoClose(fileWriter = new FileWriter("someOtherFile"));
BufferedWriter bufferedWriter =
autoClose(bufferedWriter = new BufferedWriter(fileWriter));
// ... do something with bufferedWriter
}
};
// .. other logic, maybe more AutoFileClosers
} catch (RuntimeException e) {
// report or log the exception
}
Using this approach you never have to worry about the try/catch/finally to deal with closing files again.
If this is too heavy for your use, at least think about following the try/catch and the "pending" variable approach it uses.
The colleague raises an interesting point, and there are grounds for arguing either way.
Personally, I would ignore the RuntimeException, because an unchecked exception signifies a bug in the program. If the program is incorrect, fix it. You can't "handle" a bad program at runtime.
This is a surprisingly awkward question. (Even assuming the acquire; try { use; } finally { release; } code is correct.)
If the construction of the decorator fails, then you wont be closing the underlying stream. Therefore you do need to close the underlying stream explicitly, whether in the finally after use or, more diifcult after successfully handing over the resource to the decorator).
If an exception causes execution to fail, do you really want to flush?
Some decorators actually have resources themselves. The current Sun implementation of ZipInputStream for instance has non-Java heap memory allocated.
It has been claimed that (IIRC) two thirds of the resources uses in the Java library are implemented in a clearly incorrect manner.
Whilst BufferedOutputStream closes even on an IOException from flush, BufferedWriter closes correctly.
My advice: Close resources as directly as possible and don't let them taint other code. OTOH, you can spend too much time on this issue - if OutOfMemoryError is thrown it's nice to behave nicely, but other aspects of your program are probably a higher priority and library code is probably broken in this situation anyway. But I'd always write:
final FileOutputStream rawOut = new FileOutputStream(file);
try {
OutputStream out = new BufferedOutputStream(rawOut);
... write stuff out ...
out.flush();
} finally {
rawOut.close();
}
(Look: No catch!)
And perhaps use the Execute Around idiom.
The Java SE 7 try-with-resources doesn't seem to be mentioned. It eliminates needing to explicitly do a close completely, and I quite like the idea.
Unfortunately, for Android development this sweet only becomes available by using Android Studio (I think) and targeting Kitkat and above.
Also you dont have to close all nested streams
check this
http://ckarthik17.blogspot.com/2011/02/closing-nested-streams.html
I use to close streams like this, without nesting try-catch in finally blocks
public class StreamTest {
public static void main(String[] args) {
FileOutputStream fos = null;
BufferedOutputStream bos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(new File("..."));
bos = new BufferedOutputStream(fos);
oos = new ObjectOutputStream(bos);
}
catch (Exception e) {
}
finally {
Stream.close(oos,bos,fos);
}
}
}
class Stream {
public static void close(AutoCloseable... array) {
for (AutoCloseable c : array) {
try {c.close();}
catch (IOException e) {}
catch (Exception e) {}
}
}
}
Sun's JavaDocs include RuntimeExceptions in their documentation, as shown by InputStream's read(byte[], int, int) method; documented as throwing NullPointerException and IndexOutOfBoundsException.
FilterOutputStream's flush() is only documented as throwing IOException, thus it doesn't actually throw any RuntimeExceptions. Any that could be thrown would most likely be wrapped in an IIOException.
It could still throw an Error, but there's not much you can do about those; Sun recommends that you don't try to catch them.