Closed GoogleCodeExporter closed 9 years ago
I just verified that this still exists in trunk and in the release 13 RC2.
So whoever has edit rights on tickets can update this to also have the laevl
Milestone-Release13.
Current trunk is:
http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/comm
on/io/Flushables.java
Release 13 RC2 is:
http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/comm
on/io/Flushables.java?name=v13.0-rc2#53
Original comment by laurent....@gmail.com
on 26 Jul 2012 at 4:12
Sounds reasonable...won't make it in for r13 though, but it'll be in r14.
Original comment by kak@google.com
on 26 Jul 2012 at 4:18
Interesting.
Closeables.close accepts null in order to support a specific usage pattern,
albeit not the one that the Javadoc covers. The Javadoc covers something like
this:
FileOutputStream out = new FileOutputStream("foo");
try {
// do work with out
} finally {
closeQuietly(out);
}
But we can imagine that you might want to catch any IOException now, rather
than later, in which case you'd write (h/t 2009-era Jesse Wilson):
FileOutputStream out = null;
try {
out = new FileOutputStream("foo");
// do work with out
} catch (IOException e) {
// handle this failure. There was a problem opening or writing to the file
} finally {
closeQuietly(out);
}
Would a situation like this arise for flush()?
Original comment by cpov...@google.com
on 26 Jul 2012 at 4:24
I don't know, and I don't know this Jesse Wilson gentleman (the - now - Android
guy, I assume?), but just noticed this when writing some code and showing it to
a co-worker who had noticed this behavior himself just recently, and it was
indeed code following the second pattern.
As it was in old code that I was cleaning up, I chose to closeQuietly and as I
wasn't sure if the stream implementation used would flush on close, I chose to
do it explicitly just in case for the time being. And I tend to write "2009-era
Jesse Wilson" code, apparently.
So, I guess this can arise for Flushables. :)
Doesn't mean it's warranted though.
Original comment by laurent....@gmail.com
on 26 Jul 2012 at 4:44
(Yes, the Android guy.)
I admit that I'm arguing from a position of ignorance here in that I'm not sure
I've ever seen a legitimate flush() call. I just searched over the internal
Google codebase for Flushables users, and all seem to fall into one of two
categories:
- People who are implementing an interface that includes a flush() method.
Good for them, but this doesn't tell us who ultimately calls flush() :)
- People who call flush() immediately before close(). I'm pretty sure that this
is supposed to be unnecessary, though naturally I can't find explicit
documentation to that effect.
We might imagine that someone would write "one record" and then flush.
However, the documentation for flush() emphasizes that the flushed data might
not have made it to disk, so the whole thing seems to be best effort, anyway :\
http://docs.oracle.com/javase/6/docs/api/java/io/OutputStream.html#flush%28%29
Anyway, if I'm right that the @Nullable argument serves only to support the
specific usage pattern above, then I don't think it's likely to come up with
flush(). It seems to matter only when you open a file in a try block and close
it in a finally block. Unless the flush() appears in the finally block,
there's no way for the stream to be null. But if it appears in the finally
block, it immediately precedes close(), so it should be unnecessary. The
analogy to Closeables ends up not quite holding up, thanks to the weird
situation that Closeables was designed for.
Original comment by cpov...@google.com
on 26 Jul 2012 at 9:47
Possibly we should update the Closeables doc to show off this
jessewilson/laurent.malvert technique instead of or in addition to the simpler
pattern.
Original comment by cpov...@google.com
on 26 Jul 2012 at 9:49
Regarding "it immediately precedes close(), so it should be unnecessary." I was
having a discussion with a couple of people and the conclusion was:
1. Nobody knows if there's a stream "out there" not flushing when closed.
2. There's no guarantee, javadoc says nothing about it so we *must* always call
flush.
3. `Writer.close()` and `FilterOutputStream.close()` document the flushing,,
`OutputStream.close()` says nothing about it, why?
So I can imagine that many people chose to always call flush before close.
Original comment by Maaarti...@gmail.com
on 28 Jul 2012 at 8:31
If you call flush at the end of the try block instead of in the finally block,
can't you avoid this?
Original comment by kurt.kluever
on 7 Aug 2012 at 5:51
Except you may never reach the end of the try block, and therefore never flush
before the close. The exception may not be thrown by the output stream you
wish to flush quietly but you may still want to flush what output you have and
close the stream.
Original comment by pdav...@karn.co.uk
on 7 Aug 2012 at 5:55
I still can't believe that an OutputStream implementation would require a
flush() before close(). I understand that it's not documented that way, but it
feels like the sort of thing that's undocumented simply because it's taken for
granted. I'm not thrilled that that's the best argument I have, but it would
seem at *least* as crazy for flush() to be required but for that not to be
documented.
Original comment by cpov...@google.com
on 7 Aug 2012 at 6:57
I'm with Chris on this one.
Can anybody point to real-world examples of such "non-well-behaved"
OutputStreams?
Original comment by stephan...@gmail.com
on 7 Aug 2012 at 8:32
> Except you may never reach the end of the try block, and therefore never
flush before the close. The exception may not be thrown by the output stream
you wish to flush quietly but you may still want to flush what output you have
and close the stream.
I really think you shouldn't be attempting to flush() if you got an exception
during the try block, regardless of whether it was the output stream that threw
the exception or not. What's the point? You got an exception in the block, so,
depending on what you're doing and the stream implementation, one of a few
things are possible:
- You hadn't written anything at all yet. Doesn't matter if you call flush() or
not.
- You started writing but didn't finish due to the exception. The amount you
succeeded in writing is essentially arbitrary; a flush() call serves at most to
write out a little more of that arbitrary amount than would otherwise have been
written.
- The exception did occur in a write call to the output stream; if flush() does
anything at all, it'll probably just throw too. Otherwise, the above applies.
- The exception occurred after you'd finished writing to the output stream but
before the end of the try block because you're doing something else afterwards.
In this case, you could just put a flush() call after you finish writing and
before the rest of the block.
All of this is moot, though, given that as far as we know, all
OutputStream/Writer implementations that need to flush data ensure they do so
during close(). I'm in favor of closing this issue.
Original comment by cgdecker@google.com
on 11 Mar 2013 at 9:14
Marking as obsolete now that closeQuietly itself is going away (issue 1118).
Original comment by cpov...@google.com
on 10 Dec 2013 at 9:00
This issue has been migrated to GitHub.
It can be found at https://github.com/google/guava/issues/<id>
Original comment by cgdecker@google.com
on 1 Nov 2014 at 4:13
Original comment by cgdecker@google.com
on 3 Nov 2014 at 9:08
Original issue reported on code.google.com by
laurent....@gmail.com
on 26 Jul 2012 at 4:09