为什么声明InputStream.close()会抛出IOException?

时间:2013-05-04 00:42:10

标签: java exception ioexception

声明java.io.InputStream.close()方法抛出IOException。在什么情况下会抛出这样的例外?

编辑:是的我已经阅读了javadoc。当发生I / O错误时,任何人都可以比#34;更具体。"? 关闭InputStream时会发生什么 I / O错误?

4 个答案:

答案 0 :(得分:19)

如果从文件系统读取输入流,则在关闭期间文件系统自身更新文件上的上次访问时间元数据或其他元数据时,可能会引发错误。无论如何,这种情况几乎从未发生过。

在从网络连接读取输入流的情况下,关闭时的错误更容易想到。网络套接字的正常关闭实际上涉及通过连接发送的关闭请求(TCP / IP FIN数据包),并等待另一端确认此关闭请求。 (实际上,连接的另一端然后又发送一个闭包请求,结束端确认。)因此,在套接字输入流的情况下,闭包操作实际上涉及通过连接发送流量,因此闭包可以失败并出现错误。

请注意,在许多实现中,如果流已经关闭,close()通常不会抛出IOException;它只是无声地失败再次关闭流。

答案 1 :(得分:4)

我正在查看Java源代码,并找到了一些有趣的内容,表明了IOException的原因。 InputStream 是一个抽象类。因此,我们无法预测将要关闭的输入类型,因此保持信息流动是有益的。

无论代码使用什么输入流都需要能够抛出IOException,因为关闭输入流可能会失败。如果它失败了,那么使用实现的任何东西都需要了解它,因为它很有可能需要处理。

了解Java中Exception结构的布局非常重要。当然,每个例外都会延伸Exception。但是,还有更广泛的例外类别:java.lang.IOException是其中之一,并涵盖所有可能的输入/输出异常。当我们说有一个I / O错误时,我们引用了IOException以下的任何内容。结果,许多例外延伸了这一例,例如FileNotFoundExceptionEOFException等,因为管理这些广告有一个广泛的首要例外非常重要。

因此,任何IO类都需要能够在关闭时抛出各种IOExceptions的。因此close()必须抛出IOException - 这使得它的实现能够抛出IOException的任何扩展。这就是close()抛出IOException的原因 - 继承了异常,并且在关闭流时需要能够使用任何IOExceptions。


以下是一些值得注意的情景:

  • 您不能两次关闭IOStream,但如果您这样做,通常不会抛出异常
  • 内容无法访问(例如,磁盘已卸载)(close()实际上对操作系统至关重要,因为它需要指示文件何时不再忙碌)
  • 通用来源已关闭
  • IOException的所有其他子类未涵盖的任何一般失败(例如FileNotFoundException

您可以通过运行IOException来检查导致Exception.getMessage()的原因。

答案 2 :(得分:3)

最终必须进行基础密切系统调用,例如在Linux http://linux.die.net/man/2/close上。记录该调用失败并显示EIO:“发生了I / O错误。”原因是,底层文件系统close调用可能会失败。

答案 3 :(得分:1)

我自己也很想知道这件事,几年前就这个话题做了一些研究。这就是我所知道的......

如果你查看你提供的链接中的javadoc,它会清楚地说明“InputStream的close方法什么都不做”,所以它没有办法抛出异常,对吗?但是,然后查看IOException的所有子类,您将看到有许多情况,其中inputstream的子类可能无法关闭流。所以我最好的猜测是,这个异常是为子类设计的,以便利用它。

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

在某些情况下,它只不过是一种滋扰,而在其他情况下,它清楚地表明出现了问题。这完全取决于您正在使用的输入流实现的类型。