11

一方ではInputStream、パブリックメソッドからを返すのが正しいと感じるクラスがあります。

public class MyClass {

    private File _file;

    ...

    public InputStream getInputStream() {
        return new FileInputStream( _file );
    }
}

ただし、このストリームを閉じる責任が発信者にかかるため、これを行うことにも非常に注意を払っています。この問題を回避できる可能性のある方法は何ですか?

4

4 に答える 4

9

これがあなたの目の問題である理由によって異なります。絶対に を返す必要がありInputStream、問題のファイルが大きすぎない場合は、ファイル全体をバイト配列にバッファリングし、元のストリームを閉じてreturn new ByteArrayInputStream(buf). a を閉じるByteArrayInputStream必要はありません (実際には効果がありません)。

しかし、 を返すのが「正しいと感じる」場合InputStream、呼び出し元が を期待してInputStreamいること、および終了時にストリームを閉じる必要性を含め、それに伴うすべてのことを期待することは意味がありませんか?

于 2012-11-16T16:40:16.767 に答える
4

戻るInputStreamことは本質的に悪いことではありません。リソースを閉じる責任を負わずに、呼び出し元がデータにアクセスできるようにする場合は、次のようにします。

interface InputReader {
    void readInput(InputStream is);
}
public class MyClass {
    void feed(InputReader ir){
       try(InputStream is=new FileInputStream( _file )){
          ir.readInput(is);
       }
    }
}

呼び出し元は、クローズ可能なリソースを引数として受け取る のインスタンスを指定し、InputReaderもはやそれをクローズする責任はありません。

MyClass myClass = ... ; //Get the instance
myClass.feed( new InputReader() {
    @Override
    void readInput(InputStream is){
       ... ; // Use at will without closing
    }
});

スローと例外が発生するように、InputStreamに渡す前に をデコレートすることを検討する必要があります。InputReader.close()

于 2012-11-17T08:43:12.080 に答える
2

現実的には、クラスの詳細を知らずにできることはあまりありません。MyClass のメソッドを介してファイル処理を提供し (ファイルの内容が何を意味するかを知る必要があります)、ストリームが空になったらストリームを閉じることができます。それとは別に、クラスのユーザーはこのオブジェクトに対して責任があり、実際にそれを避けることはできません。C++ のように、デストラクタの機能がなければ、クラスのスコープを離れたオブジェクトに対して 100% 責任を負うことはできません。

あなたができることはclose()、開いているファイルハンドラー、接続などをクリーンアップするメソッドをクラスに配置し、クラスのユーザーがclose(). メソッドを使用して、呼び出し元がクラスを適切に閉じているかどうかを追跡する方法については、この質問を参照してください。finalize

于 2012-11-16T16:39:03.100 に答える
1

...このストリームを閉じる責任が発信者に課せられるためです。

はい、呼び出し元は、返されたストリームの終了操作を処理する責任があります。メソッドが返されたものを追跡する方法がないため、このタスクは完全に呼び出し元に属します。この場合と例外の使用には類似点があります。APIの作成者は、提示する内容を常に制御できるとは限らないため、開発者は例外を使用します。数値をゼロで割る可能性がある場合など、注意が必要です。

于 2012-11-16T16:37:42.390 に答える