web-dev-qa-db-ja.com

OutputStreamが閉じているかどうかを確認する方法

とにかく、それへの書き込みを試みたりIOExceptionをキャッチしたりせずに、OutputStreamが閉じているかどうかを確認する方法はありますか?

たとえば、次の不自然な方法を考えてみます。

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

何を置き換えますか/* stream isn't closed */とは?

28
chrisbunney

基盤となるストリームは、書き込みを試みるまで(たとえば、ソケットのもう一方の端で閉じられた場合)、閉じられていることを認識できない場合があります。

最も簡単なアプローチは、最初にテストするのではなく、それを使用して、それが閉じた場合に何が起こるかを処理することです。

何をテストしても、常にIOExceptionが発生する可能性があるため、例外処理コードを回避することはできません。このテストを追加すると、コードが複雑になる可能性があります。

32
Peter Lawrey

残念ながら、OutputStream APIにはisClosed()のようなメソッドがありません。

したがって、私が知っている明確な方法は1つだけです。他の出力ストリームをラップし、そのclose()メソッドを次のように実装するクラスStatusKnowingOutputStreamを作成します。

_public void close() {
    out.close();
    closed = true;
}
_

ここでメソッドisClosed()を追加します

_public boolean isClosed() {
    return closed;
}
_
9
AlexR

OutputStream自体は、このようなメソッドをサポートしていません。 Closableインターフェースは、close()を呼び出すと、そのOutputStreamを破棄するように定義されています。

おそらく、アプリケーションの設計を少し見直して、なぜそれを行わないのかを確認し、アプリケーション内でまだ実行されている閉じられたOutputStreamインスタンスになってしまう可能性があります。

2
jbx
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;
}

これはFileOutputStreamでのみ可能です!

2
Joop Eggen

いいえ。独自のクラスを実装する場合は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 {
}
1
Kylar