web-dev-qa-db-ja.com

FileReaderとBufferedReaderの両方をclose()する必要がありますか?

FileReaderにラップされたBufferedReaderを使用してローカルファイルを読み取っています。

BufferedReader reader = new BufferedReader(new FileReader(fileName));
// read the file
// (error handling snipped)
reader.close();

close()FileReaderも必要ですか、それともラッパーが処理しますか?私は人々がこのようなことをするコードを見てきました:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);
// read the file
// (error handling snipped)
bReader.close();
fReader.close();

このメソッドはサーブレットから呼び出されます。ハンドルを開いたままにしないでください。

177
Zilk

番号。

BufferedReader.close()

BufferedReader および InputStreamReader のjavadocに従ってストリームを閉じます

と同様

FileReader.close()

します。

198
Atmocreations

他の人が指摘したように、外側のラッパーを閉じるだけで済みます。

BufferedReader reader = new BufferedReader(new FileReader(fileName));

BufferedReaderコンストラクターが例外(たとえば、OutOfMemoryError)をスローした場合、これがファイルハンドルをリークする可能性は非常にわずかです。アプリがこの状態にある場合、クリーンアップの注意は、OSから他のプログラムに割り当てるリソースを奪わないことがどれだけ重要かによって異なります。

ラッパーコンストラクターがJava 5または6で失敗する可能性がある場合、 Closeable インターフェイスを使用できます。

Reader reader = new FileReader(fileName);
Closeable resource = reader;
try {
  BufferedReader buffered = new BufferedReader(reader);
  resource = buffered;
  // TODO: input
} finally {
  resource.close();
}

Java 7コードはtry-with-resourcesパターンを使用する必要があります。

try (Reader reader = new FileReader(fileName);
    BufferedReader buffered = new BufferedReader(reader)) {
  // TODO: input
}
93
McDowell

BufferedReaderのソースによると、この場合はbReader.closeがfReader.closeを呼び出すため、技術的には後者を呼び出す必要はありません。

5
Csaba_H

BufferedReader のソースコードは、BufferedReaderを閉じると、基盤が閉じていることを示しています。

4
Brian Agnew

ソースコードをチェックした後、私は例のためにそれを見つけました:

FileReader fReader = new FileReader(fileName);
BufferedReader bReader = new BufferedReader(fReader);

上のclose()メソッド BufferedReader オブジェクトは、次の抽象close()メソッドを呼び出します 読者 最終的に実装されたメソッドを呼び出すクラス InputStreamReader その後、クラス InputStream オブジェクト。

したがって、bReader.close()のみで十分です。

3
Anup Verma

Java 7以降では、 try-with-resources Statement を使用できます

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

BufferedReaderインスタンスはtry-with-resourceステートメントで宣言されているため、tryステートメントが正常に完了したか、突然終了したかに関係なく閉じられます。したがって、finallyステートメントで自分で閉じる必要はありません。 (これは、ネストされたリソースステートメントの場合も同様です)

これは、リソースを操作するための推奨される方法です。詳細については、 documentation を参照してください

1
Claudiu

遅れましたが:

BufferReader.Java:

public BufferedReader(Reader in) {
  this(in, defaultCharBufferSize);
}

(...)

public void close() throws IOException {
    synchronized (lock) {
        if (in == null)
            return;
        try {
            in.close();
        } finally {
            in = null;
            cb = null;
        }
    }
}
0

ラップされたリーダー/ライターを閉じる必要はありませんしないでください

ドキュメントをご覧になった場合( Reader.close()Writer.close() )、Reader.close()で次のように表示されます:

ストリームを閉じて、それに関連付けられているシステムリソースを解放します。

これは、「システムリソースが関連付けられているをすべて解放する」というだけです。確認はしていませんが..深く見始めるためのナッジを提供します。そして、Writer.close()に行くと、それは自分自身を閉じることだけを示します。

そのような場合、ソースコードを見るために OpenJDK を参照します。

BufferedWriterで 265行目out.close()が表示されます。だから、それはそれ自体を閉じていません。それは何か他のものです。クラスの「out」の出現を検索すると、コンストラクターの 87行目 で、そのoutはクラスが別のコンストラクターを呼び出す場所をラップするライターであることがわかります。 outパラメーターを独自のout変数に割り当てます。

だから..他の人はどうですか?同様のコードは BufferedReader Line 514BufferedInputStream Line 468 および InputStreamReader Line 199 で確認できます。他の人は知りませんが、これで十分だと思います。

0

BufferedReader、つまりreader.close()を閉じるだけで問題なく動作します。

0
robust12