Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检查OutputStream是否已关闭_Java_Outputstream_Java Io - Fatal编程技术网

Java 如何检查OutputStream是否已关闭

Java 如何检查OutputStream是否已关闭,java,outputstream,java-io,Java,Outputstream,Java Io,在不尝试写入并捕获IOException的情况下,是否仍然可以检查OutputStream是否已关闭 例如,考虑下面的设计方法: public boolean isStreamClosed(OutputStream out){ if( /* stream isn't closed */){ return true; }else{ return false; } } 您可以用什么替换/*流未关闭*/?在您尝试写入之前,底层流可能不知道它已关

在不尝试写入并捕获
IOException
的情况下,是否仍然可以检查OutputStream是否已关闭

例如,考虑下面的设计方法:

public boolean isStreamClosed(OutputStream out){
    if( /* stream isn't closed */){
        return true;
    }else{
        return false;
    }
}

您可以用什么替换
/*流未关闭*/

在您尝试写入之前,底层流可能不知道它已关闭(例如,如果套接字的另一端将其关闭)

最简单的方法是使用它并处理它关闭时发生的情况,而不是先测试它


无论您测试什么,都有可能得到IOException,因此无法避免异常处理代码。添加此测试可能会使代码复杂化。

OutputStream本身不支持这种方法。 Closable接口的定义方式是,一旦调用close(),您将处理该OutputStream


也许你应该重新审视一下应用程序的设计,检查一下为什么不这么做,结果是应用程序中仍然有一个封闭的OutputStream实例在运行。

不。如果你实现了自己的,你可以编写一个isClosed方法,但如果你不知道具体的类,那么不是。OutputStream只是一个抽象类。以下是它的实现:

   /**
 * Closes this output stream and releases any system resources 
 * associated with this stream. The general contract of <code>close</code> 
 * is that it closes the output stream. A closed stream cannot perform 
 * output operations and cannot be reopened.
 * <p>
 * The <code>close</code> method of <code>OutputStream</code> does nothing.
 *
 * @exception  IOException  if an I/O error occurs.
 */
public void close() throws IOException {
}

不幸的是,OutputStream API没有类似于
isClosed()
的方法

因此,我只知道一种明确的方法:创建类
StatusKnowingOutputStream
,该类封装任何其他输出流并实现其
close()
方法,如下所示:

public void close() {
    out.close();
    closed = true;
}
现在添加方法
isClosed()

这仅适用于FileOutputStream

通过使用out.checkError()


在这里找到它:

如果您在测试中执行此操作,请使用mockito间谍,然后执行
验证

我进行了一次有效的测试

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import java.io.InputStream;

class MyTest {
    @Test
    public void testInputStreamCloseCalled() throws IOException {
        final InputStream spied = spy(...)
    
        // Do something that should call .close() on the spied InputStream
        spied.close()

        verify(spied, times(1)).close();
    }
}
其中,
是您正在处理的输入流


也适用于OutputStreams。

您需要解决的基本问题是什么?我怀疑OP希望避免处理异常。(这源于我对可能收到的不良输入进行了辩护,但这更多的是一个假设性问题,加上谷歌“java检查outputstream是否已关闭”的顶级结果,这似乎并没有真正回答这个问题,它不是
outputstream
一个抽象类,因此它可以提供一些实现?是的,对不起,我的错。是的,遗憾的是它没有像@AlexR在他的答案()中所建议的那样做,但是这在任何应用程序中都不应该是必需的。如果您自己的代码关闭了流,那么它也应该处理它的状态(关闭/打开)。但是,如果您从某个第三方库获取流,它应该提供一些
布尔canIUseTheStream()
方法。@bezmax,处理其状态可能会有点困难,比如说,如果您希望在业务方法中关闭它(您需要关闭它才能将其发送到其他地方)但是您也需要在
finally
子句中处理它,以便在发生异常时关闭它。这是一个好主意,但对于一般用途来说绝对不够。可能存在从包装器外部关闭流的情况,例如由操作系统或流提供程序关闭流。将此答案与其他答案区分开来的原因是,没有诸如
isClosed()
,“底层流在尝试写入之前可能不知道它已关闭”,因此被接受,谢谢:)在您调用close()之后,isClosed()是真的。这不是大多数人希望它做的事这可能适用于System.out PrintStream,事实上也适用于任何PrintStream,但通常不适用于OutputStreams。
public boolean isStreamClosed(FileOutputStream out){
    try {
        FileChannel fc = out.getChannel();
        return fc.position() >= 0L; // This may throw a ClosedChannelException.
    } catch (java.nio.channels.ClosedChannelException cce) {
        return false;
    } catch (IOException e) {
    }
    return true;
}
while(!System.out.checkError()) {
    System.out.println('hi');
}
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import java.io.InputStream;

class MyTest {
    @Test
    public void testInputStreamCloseCalled() throws IOException {
        final InputStream spied = spy(...)
    
        // Do something that should call .close() on the spied InputStream
        spied.close()

        verify(spied, times(1)).close();
    }
}