Re: Closing Files that Weren't Successfully Opened
Stanimir Stamenkov <s7an10@netscape.net> wrote:
Mon, 14 Mar 2011 15:27:26 -0700 (PDT), /KevinSimonson/:
My question is this. If I declare a variable <scnnr> to be of type
<Scanner>, and try to open it with the statement <scnnr = new
Scanner( new File( "Xy.Txt"))>, and a <FileNotFoundException> gets
thrown, should I still do a <scnnr.close()>, say in the <catch>
block? And similarly, if I declare <prntWrtr> to be of type
<PrintWriter> and try to open it with the statement <prntWrtr =
new PrintWriter( new BufferedWriter( new FileWriter( "Xy.Txt")))>,
and an <IOException> gets thown, should I still do a
<prntWrtr.close()>, also probably in the <catch> block? Or in each
such situation can I conclude that since an exception occurred
while I was attempting to open the respective file, the variables
will still each both be <null>, and therefore I don't have to do
anything?
As you've noticed, if the object constructor throws, you'll get no
object reference to invoke a method on. It is responsibility of the
construction code to clean any unreachable resources allocated prior
throwing the exception.
This responsibility covers only stuff that has been allocated within
that constructor that throws. If Scanner were to throw, then it would
not clean up the open File passed to it.
To solve it correctly, you(the OP) do your construction work stepwise:
File file; Scanner scnnr;
try {
file = new File ("Xy.Txt");
scnnr= new Scanner ( file );
} catch (FileNotFoundException e) {
if (file != null) { file.close(); }
... other cleanup
} catch (SomeOtherException e) {
// ditto
} ...
Yes, that isn't as "beautiful" as putting several "new"s into a single
line, but as you saw, that beauty came with a price (possible ressource-
leakage), that you seem not to like (and correctly so).