Using finally keyword on InputStream#close() - java

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.

Related

difference between two types of try catch block

I recently saw a code...
try ( Socket socket = new Socket("localhost", 2003);
Writer writer = new OutputStreamWriter(socket.getOutputStream());){
writer.write("data");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
in this code try catch is used as try ( somecode ){ again some code } catch(){};
and it is working fine;
then i tried this code in this way
try {
Socket socket = new Socket("localhost", 2003);
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("data");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
here try catch is used as try { again some code } catch(){};
which is also working... i was familiar with this pattern already...
so my question is ...
What is the difference between these two ways of implementation of try catch ???
The first solution is an example of "try-with-resources", where you declare your resources accessible inside the try block.
This is always possible if you work with instances of AutoClosable. Java will close these resources for you in an implicit finally block after your last line inside the try terminates. This is extremely useful as you don't need to take care of releasing these resources on your own.
The second example just doesn't close the socket and writer and thus is not 100% functionally equal to solution 1.
Java 1.7 introduced feature of try with resources where you don't need to explicitly close the resources which you open in try block
Prior to 1.7, you would always have to remember to close the resources in finally block.
Provided all the resources that you open in try() block implement autoclosable interface
https://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html
The second needs finally {} to close Socket & Writer.The first will be closed automatically.And the first needs jdk1.7 or later.

Does finally completely execute if an exception is thrown within finally block

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

Does close()ing InputStream release resoures even if it throws?

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.

What is the correct way to silently close InputStream in finally block without losing the original exception?

I am wondering if the below code closes InputStream in finally block correctly
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
is.close();
} catch(IOException e) {
}
}
If an exception happens during is.read() will be it ignored / suppressed if an exception happens during is.close()?
Best way is to use Java 7 and use try with resources, or do same thing manualy and add exception from closing as suppressed exception.
Pre Java 7:
If you are throwing your custom exception, you can add in it supressed exception like it is done in Java 7 (in your exception create fields List suppressed and put there exceptions from close operation and when dealing with your exception, look there too.
If you cannot do that, I don't know anything better than just log it.
examples:
from Java tutorials
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
but better form is:
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
This way even if creation of FileReader is succesfull but creation of BufferedReader fails (eg not enough memory), FileReader will be closed.
You can close it with IOUtils from https://commons.apache.org/proper/commons-io/
public void readStream(InputStream ins) {
try {
//do some operation with stream
} catch (Exception ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(ins);
}
}
The Java 6 specs say
If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
So you are right, you will lose the original exception.
The solution probably is to write your finally block so defensively that it is a bigger surprise (worth propagating) if the finally block fails than if an exception comes out of the try catch block.
So, for example, if it is possible that the stream may be null when you try to close it, check it:
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
if( is!=null ) {
is.close();
}
} catch(IOException e) {
}
}
In Java 7, Alpedar's solution is the way to go of course.
The exception from is.close() will be suppressed and the exception from is.read() will be the one that propagates up.
With the code you posted:
If is.close() throws an IOException, it gets discarded and the original exception propagates.
If is.close() throws something else (a RuntimeException or an Error), it propagates and the original exception is discarded.
With Java 7, the correct way to close an InputStream without loosing the original exception is to use a try-with-resources statement:
try (InputStream is = new FileInputStream("test")) {
for(;;) {
int b = is.read();
// ...
}
}
Prior to Java 7, what you do is just fine, except you may want to catch all exceptions instead of just IOExceptions.
Based on your code sample if an exception occurs at the int b = is.read(); point, then the exception will be raised higher up the call chain.
Note though that the finally block will still execute and if the Inputstream invalid another exception will be thrown, but this exception will be "swallowed", which may be acceptable depending on your use case.
Edit:
Based on the title of your question, I would add that what you have is fine in my opinion. You may want to additionally add a catch block to explicitly handle (or perhaps wrap) any exception within the first try block, but it is also acceptable to let any IO exceptions raise up - this really depends on your API. It may or may not be acceptable to let IO exceptions raise up. If it is, then what you have it fine - if it isn't then you may want to handle/wrap the IO exception with something more suitable to your program.
How about the next solution:
InputStream is = new FileInputStream("test");
Exception foundException=null;
try {
for(;;) {
int b = is.read();
...
}
} catch (Exception e){
foundException=e;
}
finally {
if(is!=null)
try {
is.close();
} catch(IOException e) {
}
}
//handle foundException here if needed
If an exception happens during is.read() will be it ignored / suppressed if an exception happens during is.close()?
Yes. You have a catch block for the exception in close() which does not re-throw the exception. Ergo it is not propagated or rethrown.
This is the sample to help to understand your problem,
if you declare the scanner in the try-catch block it will give compiler warning the resource is not closed.
so either make it locally or just in try()
import java.util.InputMismatchException;
import java.util.Scanner;
class ScanInt {
public static void main(String[] args) {
System.out.println("Type an integer in the console: ");
try (Scanner consoleScanner = new Scanner(System.in);) {
System.out.println("You typed the integer value: "
+ consoleScanner.nextInt());
} catch (InputMismatchException | ArrayIndexOutOfBoundsException exception) {
System.out.println("Catch Bowled");
exception.printStackTrace();
}
System.out.println("----------------");
}
}

Java code style for open stream try/finally block [duplicate]

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.

Categories

Resources