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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16369462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:47:01  来源:igfitidea点击:

Why is InputStream.close() declared to throw IOException?

javaexceptionioexception

提问by meriton

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

java.io.InputStream.close()方法被声明为抛出一个IOException. 在什么情况下会真正抛出这样的异常?

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

编辑:是的,我已经阅读了 javadoc。有人能比“发生 I/O 错误时”更具体吗?关闭? 时会发生什么I/O 错误InputStream

采纳答案by Konstantin Yovkov

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 timemetadata, 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.

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

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

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

回答by Konstantin Yovkov

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

我正在浏览 Java 源代码,并发现了一些有趣的东西,这表明了IOException原因。InputStream是一个抽象类。因此,我们无法预测将关闭的输入类型,因此保持信息流动是件好事。

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.

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

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.IOExceptionis 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.

了解 Java 中 Exception 结构的布局很重要。当然,每个异常都扩展了Exception。但是,还有更广泛的异常类别:java.lang.IOException是其中之一,并涵盖所有可能的输入/输出异常。当我们说存在 I/O 错误时,我们指的是属于IOException. 因此,许多异常扩展了这个异常,例如FileNotFoundExceptionEOFException等,因为拥有一个广泛的、总体的异常来管理这些异常很重要。

As a result, any IO class will need to be able to throw anyof the various IOExceptions on close. close()therefore must throw IOException- this gives its implementation the ability to throw any of the extensions of IOExceptionas 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.

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



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)
  • 您不能关闭 IOStream 两次,但如果这样做通常不会引发异常
  • 内容变得不可访问(例如磁盘被卸载)(这close()对操作系统来说实际上是至关重要的,因为它需要有一个指示文件何时不再繁忙)
  • 通用源已关闭
  • IOException(例如FileNotFoundException)的所有其他子类未涵盖的任何通用故障

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

您可以检查是什么导致了IOException运行Exception.getMessage().

回答by Kevin

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 closecall can fail.

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

回答by smallworld

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.

如果您查看您提供的链接中的 javadoc,它清楚地指出“InputStream 的 close 方法什么都不做”,所以它不可能抛出异常,对吗?但是然后查看 IOException 的所有子类,您会发现在很多情况下 inputstream 的子类可能无法关闭流。所以我最好的猜测是这个异常是为子类设计的以使用它。

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

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.

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