The problem with that, is two fold:

1) It's easy to forget to write 'flush()'. I suggest a code checker or
an annotation processor that warns you if you forget, and

2) Theoretically, flush() does slightly less than close(). For
example, close() will also have to update certain file descriptors,
depending on file system. It's quite rare, so not that big of a deal,
but nevertheless, in rare cases, your program will silently not make a
file. Good thing it's rare, because silently failing to save data is a
massive disaster.

FWIW, until java 7 comes along, its really easiest to just use a
'closure' - an anonymous inner handling class. Something like:

try {
    InputStream in = getStream();
    SafeIO.go(in, new SafeIO.Input() { public void handle(InputStream
in) {
        //do stuff here
    }});
} catch ( IOException e ) {
    //handle exceptions here.
}

you'll need to roll SafeIO yourself, include a bunch of interfaces,
and matching 'go' methods for each type of resource (InputStream,
OutputStream, Reader, Writer...) - but its still easier to read than
the alternative.

On Jun 4, 3:54 am, RogerV <[email protected]> wrote:
> On OutputStream I do a flush() explicitly in the try block instead of
> relying on close() to do the buffer flush.
>
> The finally() block then does the close() and swallows the close()
> exception.
>
> If there was a problem on the flush() then the exception will be
> caught in the catch() block and will be plain to see without having
> been swallowed.
>
> --Roger
>
> On Jun 2, 10:07 pm, Mark Hibberd <[email protected]> wrote:
>
> > On Wed, Jun 3, 2009 at 12:55 PM, Christian Catchpole
>
> > <[email protected]> wrote:
>
> > > Yeah, this can be a problem.  Perhaps the neatest way is to do
> > > something like this..  use a static helper which eats the exception.
>
> > > OutputStream os = new BlahOutputStream();
> > > try {
> > >   // do stuff hyar, hyar and hyar..
> > >   os.write( stuff );
> > > } finally {
> > >   StreamHelperThingy.closeDontThrow(os);
> > > }
>
> > That is probably ok for an InputStream but it is definitely not  for
> > an OutputStream. If there is buffering going on, flush will get called
> > via the close method, triggering an exception and your data would not
> > have been written. With your example you would never find that out.
>
> > You only want to swallow an exception thrown from close if there was
> > an exception from the try. I would recommend writing something like:
>
> > class WithOutputStream {
> >   public static <T> T blah(UsingOutputStream<T> action) {
> > OutputStream os = new BlahOutputStream();
> >   }
>
> > }
>
> > class
>
> > > On Jun 3, 10:01 am, Tim <[email protected]> wrote:
> > >> In Joshua Bloch's Automatic Resource Management proposal
> > >> (http://docs.google.com/Doc?id=ddv8ts74_3fs7483dp) for project Coin he
> > >> wrote:
>
> > >>     Even the "correct" idioms for manual resource management are
> > >> deficient:
> > >>     if an exception is thrown in the try block, and another when
> > >> closing the
> > >>     resource in the finally block, the second exception supplants the
> > >>     first, making it difficult to determine the real cause of the
> > >> trouble.
> > >>     In other words, by responsibly closing your resource even during
> > >> some
> > >>     catastrophic event, you can actually erase all record of the
> > >> event,
> > >>     resulting in many wasted hours of debugging. While it is possible
> > >> to
> > >>     write code to suppress the second exception in favor of the first,
> > >>     virtually no one does, as it is just too verbose. This is not a
> > >>     theoretical problem; it has greatly complicated the debugging of
> > >> large
> > >>     systems.
>
> > >> I just encountered this problem: Some code threw an exception creating
> > >> a zip.
> > >> The ZipOutputStream was closed in a finally block and the real
> > >> exception
> > >> was replaced by one complaining that there were no entries in the zip.
>
> > >> Does anyone do the "right" thing?  What are the best idioms or helper
> > >> methods/classes to do this?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to