32

The java.io.InputStream.close() method is declared to throw an IOException. Under what circumstances would such an exception actually be thrown?

Edit: Yes I have read the javadoc. Can anybody be more specific than "when an I/O error occurs"? What I/O error can occur while closing an InputStream?

4
  • 6
    if an I/O error occurs. Commented May 4, 2013 at 0:45
  • Maybe if it is already closed? Commented May 4, 2013 at 0:45
  • @meriton I think you will find your answer to "What I/O error can occur... " question in the IOException class not in InputStream class javadoc. As mentioned in my answer I too expected it to be in InputStream, could not find it and had my "Ahha" moment when looking at all the subclasses of IOException. Commented May 4, 2013 at 1:02
  • 4
    @Martinsos: The JavaDoc of java.io.Closable.close writes: If the stream is already closed then invoking this method has no effect. Commented May 4, 2013 at 1:05

4 Answers 4

21

In the case of input stream reading from a file system, an error can be raised while the file system itself updates the last access time metadata, or some other metadata, on a file during closure. Anyway, this happens almost never in practice.

In the case of an input stream reading from a network connection, an error on closure is a bit more conceivable. A normal closure of a network socket actually involves a closure request (TCP/IP FIN packet) being sent over the connection and waiting for the other end to acknowledge this closure request. (In fact, the other end of the connection then in turn sends a closure request, which the closing end acknowledges.) So in the case of a socket input stream, a closure operation actually involves sending traffic over the connection and the closure can thus fail with an error.

Note that in many implementations, close() generally doesn't throw an IOException if the stream is already closed; it simply fails silently to close the stream again.

Sign up to request clarification or add additional context in comments.

Comments

5

I'm looking through the Java source code, and have found something interesting which is indicative of the IOException reason. InputStream is an abstract class. We therefore can't predict the kind of input which will be closed, so it's good to keep information flowing.

Whatever code uses that input stream needs to be able to throw an IOException, because there is a chance that closing the input stream may fail. If it fails, whatever's using the implementation needs to know about it, because there's a good chance it needs to be handled.

It's important to understand the layout of the Exception structure in Java. Every exception, of course, extends Exception. However, there are also broader categories of exceptions: java.lang.IOException is one of these, and covers all possible input/output exceptions. When we say there has been an I/O error, we're referencing anything which falls under IOException. As a result, many exceptions extends this one, e.g. FileNotFoundException, EOFException, etc. as it's important to have a broad, overarching exception to manage these.

As a result, any IO class will need to be able to throw any of the various IOExceptions on close. close() therefore must throw IOException - this gives its implementation the ability to throw any of the extensions of IOException as well. This is why close() throws IOException - exceptions are inherited, and you need to be able to any of the IOExceptions when closing a stream.


Here are a couple scenarios worth noting:

  • You can't close an IOStream twice, though this generally doesn't throw an exception if you do
  • The content becomes inaccessible (e.g. a disk was unmounted) (The close() is actually critical for the operating system, as it needs to have an indicator of when the file is no longer busy)
  • The generic source has closed
  • Any generic failure not covered by all other subclasses of IOException (e.g. FileNotFoundException)

You can check what caused an IOException by running Exception.getMessage().

7 Comments

Closing a closed stream "has no effect" according to the JavaDoc of java.io.Closable.close. As for the other causes, I see how they could occur when opening or reading from a stream, but when closing?
@mertion Well... yes. For instance, if you're reading from a disk, the closure step is critical in telling the operating system nothing's using the file anymore. If the program can't do that, it makes sense to alert the program.
@meriton I figured out the exact reason why it exists. Please see my edits.
Why could telling the operating system that it may free the file descriptor fail? And what good would it to to tell the program about that? I mean, if the operating system won't close the file when asked, what can the progam do?
I may be wrong, but it seems like throwing some kind of unchecked Exception would have been a better design choice for the close() operation.
|
4

The underlying close system call will have to be made eventually, e.g. on linux http://linux.die.net/man/2/close. That call is documented to fail with EIO: "An I/O error occurred." So the reason is, that the underlying file system close call can fail.

Comments

1

I have wondered about this myself and have done a little research on this topic few years ago. This is what I know....

If you look at the javadoc in the link you provided, it clearly states that "The close method of InputStream does nothing", so there is no way it would throw an exception, correct? But then looking at all of the subclasses of IOException you will see that there are many situations where subclasses of inputstream may not be able to close the stream. So my best guess is that this exception is designed for subclasses to make use of it.

http://docs.oracle.com/javase/6/docs/api/java/io/IOException.html

In some cases, it is nothing more than a nuisance, and in others it clearly indicates that something went wrong. It all depends on what type of inputstream implementation you are making use of.

1 Comment

And by the way, StackOverflow showed me this in the right column which I thought was an interesting discussion on a very similar topic. See if this helps explain... stackoverflow.com/questions/2766450/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.