web-dev-qa-db-ja.com

常にBufferedReaderを閉じる必要がありますか?

ファイルをListに読み込む行は次のとおりです。

List<String> lines =
    new BufferedReader(
        new InputStreamReader(classLoader.getResourceAsStream(fileName)))
            .lines()
            .collect(Collectors.toList());

これは正しいですか、または後で閉じることができるようにBufferedReaderを変数に割り当てる必要がありますか?

10
Ekaterina

常にリソースを閉じる必要があります。ほとんどの成熟したOSはプロセスが完了するとファイルを閉じるので、ファイルを2、3しか使用しない小さなプログラムでは、閉じることは大きな問題にはなりません。ただし、通常、一度に開くことができるファイルの数には制限があります。より大きなプログラムを書き始めるときにこれらの制限に達しないように、整頓するのは良いことです。ネットワークやシリアルポートなど、他の種類のリソースもあります。プログラムがまだ実行されている場合でも、プログラムの処理が完了したら、他のユーザーに使用を許可することができます。

ファイルを手動で閉じる代わりに、 try-with-resources 構文を使用することで、エラーが発生した場合でもファイルを適切に閉じることができます。

List<String> lines;
try(BufferedReader reader = new BufferedReader(
        new InputStreamReader(classLoader.getResourceAsStream(fileName)))) {
    lines = reader.lines().collect(Collectors.toList());
}
11
Mad Physicist

さて、あなたの具体的な例では、ストリームは

classLoader.getResourceAsStream(fileName)

決して閉じられません。このストリームは閉じる必要があります-ローカルシステムのファイルハンドルである可能性があります。これを閉じるには、BufferedReaderを閉じます。これにより、ラップされたInputStreamReaderが閉じ、基になるInputStreamが閉じます。代わりに、元のInputStreamへの参照を保存して、これだけを閉じることもできます。

try-with-resources も確認してください。これにより、ここでの作業が容易になる可能性があります。

6

正直しました


ドキュメントから:ストリームにはclose()メソッドがあり、実装AutoCloseableインターフェースがありますが、実際にはほとんどすべてのストリームインスタンスを使用後に閉じる必要はありません。

一般に、ソースがIOチャネルであるストリームのみ、たとえばBufferedReader.lines閉じる必要があります。

ほとんどのストリームは、特別なリソース管理を必要としないコレクション、配列、または生成関数によってサポートされています。 ストリームを閉じる必要がある場合は、try-with-resourcesステートメントでリソースとして宣言できます。

0
MS90