找出InputStream是否关闭

use*_*408 2 java inputstream

java.io.InputStream在尝试读取a 之前,Java是否有任何可靠的方法来确定a 是否关闭?

我的用例是我有一个接受InputStream参数并从中读取参数的方法。该方法在其自己的线程中运行,如果输入流关闭,我想终止该线程。

InputStreamImplements Closeable,它提供一种close()方法,但显然无法查询实例是否已关闭。

尝试从封闭状态读取InputStream将引发IOException,但可能还有其他原因,并且接口合同中没有任何内容说明这种情况是否永久存在,或者在某些情况下是否有可能在某个时候消失。

我的方法的调用者可以提供所需的任何子类InputStream,因此不能依靠特定的子类行为。

还有其他想法吗?

eri*_*son 6

否。没有用于确定流是否已关闭的API。

应用程序应该(并且通常)设计的,因此不必显式跟踪流的状态。流应该在ARM块中打开并可靠地关闭,并且在该块内部,应该安全地假定流是打开的。当惯用ARM块时,它自然会将引用的作用域限定为流,以便在关闭流之后没有人可以访问它。

可以通过多种方法在逻辑上“关闭”流,并且许多流实现在进行read()调用之前不会检测到此情况。例如,如果服务器关闭套接字,则客户端中套接字对象的内部状态不太可能异步反映这一情况。相反,下一次读取数据的调用将检测到关闭并更新状态。在此示例中,如果完全关闭了套接字,则read()调用将返回EOF以向应用程序发出信号,表明已安全接收所有数据。如果连接异常终止,则调用将引发异常,以指示某些数据可能已丢失。

可以合理地假设抛出an的流IOException已死,并且进一步尝试读取该流将继续失败。如果您可能在调用之前检测到了这种情况read(),则可能仍可以以相同的方式处理它。

此方法的例外是某些流支持读取超时,如果一段时间未收到任何输入,则会引发异常,但该流仍然有效。对于调用方来说,将此类流传递给显式支持重试读取的方法才有意义。


Jos*_*ero 1

我认为最干净的方法是添加一个自定义类,该类扩展您想要使用的任何类型的 InputStream。将其添加到您的 utils 包或其他东西中。并且在该类中有一个名为:

private boolean isClosed = false;
Run Code Online (Sandbox Code Playgroud)

因此,当您调用 close 时,您可以执行以下操作:

@Override
public void close() throws IOException {
    if(!isClosed){
        super.close();
        isClosed = true;
    }
}

public boolean isClosed() {
    return isClosed;
} 
Run Code Online (Sandbox Code Playgroud)

在我看来,这将是满足您的具体要求的最干净的方式。您还可以通过在不同场景下返回特定自定义错误的方式来管理错误。