JavaのBufferedInputStreamクラスの使い方を徹底解説!closeメソッドで安全にストリームを閉じよう
生徒
「Javaでファイルを読み込んだあとって、何か特別な処理って必要なんですか?」
先生
「はい、Javaではファイルを読み込んだり書き込んだりしたあとに、ストリームを閉じる必要があります。そのときに使うのがcloseメソッドです。」
生徒
「えっ、閉じないとどうなるんですか?」
先生
「実はストリームを閉じ忘れると、メモリを使い続けたり、ファイルがロックされたままになったりして、問題が起きることがあるんです。今日はBufferedInputStreamクラスとcloseメソッドの基本を一緒に学びましょう。」
1. JavaのBufferedInputStreamクラスとは
BufferedInputStreamクラスは、Javaで効率よくデータを読み込むために使われる入力ストリームです。特にファイルからバイナリデータを読み取るときによく使われます。内部にバッファ(データの一時保存場所)を持っているため、ディスクから一度にある程度のデータを読み込むことで、読み取りの回数を減らし、処理を高速化できます。
Javaでは、直接ファイルから1バイトずつ読み込むよりも、BufferedInputStreamのようなバッファ付きのストリームを使った方がパフォーマンスが良くなります。
2. closeメソッドとは?なぜ必要なの?
closeメソッドは、Javaのストリームを使い終わったあとに呼び出して、リソース(メモリやファイルハンドル)を解放するためのメソッドです。これを呼ばないと、メモリやファイルがずっと占有されたままになる可能性があり、アプリケーションの動作に悪影響を及ぼします。
特にBufferedInputStreamなどのInputStream系のクラスは、ファイルやネットワークといった外部リソースを扱うため、必ずcloseで明示的に閉じる必要があります。
3. BufferedInputStreamとcloseメソッドの基本的な使い方
それでは、BufferedInputStreamでファイルを読み込んで、最後にcloseメソッドで閉じるという基本的なサンプルコードを見てみましょう。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class CloseExample {
public static void main(String[] args) {
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream("sample.txt"));
int data;
while ((data = bis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
このように、finallyブロックの中でcloseメソッドを呼び出すことで、例外が発生した場合でも確実にストリームを閉じることができます。
4. try-with-resources構文で自動的にcloseを呼び出す
Java7以降では、try-with-resources構文を使うことで、明示的にcloseを呼び出さなくても、自動的にリソースを解放してくれるようになりました。これを使えばコードもスッキリします。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("sample.txt"))) {
int data;
while ((data = bis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
この構文を使えば、ストリームがブロックを抜けるタイミングで自動的にcloseが実行されるため、finallyブロックで明示的に書く必要がなくなります。
5. closeメソッドに関するよくあるミスと注意点
closeメソッドを正しく使わないと、プログラムに不具合が発生することがあります。以下の点に注意しましょう。
- closeを呼び忘れる:リソースが開きっぱなしになると、ファイルがロックされたままになり、他の処理で開けなくなることがあります。
- nullのままcloseを呼ぶ:ストリームが生成できなかった場合、nullのまま
closeを呼ぶとNullPointerExceptionになります。 - 複数のストリームを開いたときの順番:複数のストリームを開いた場合、
closeは開いた順とは逆順で閉じるのが基本です。
6. BufferedInputStreamを使うときのclose以外のポイント
BufferedInputStreamを使うときには、close以外にもいくつか押さえておきたいポイントがあります。
- バッファサイズはデフォルトで8192バイト:必要であればコンストラクタでバッファサイズを変更できます。
- readメソッドでバッファごと読み込むことも可能:1バイトずつよりも複数バイト読み込む方が高速です。
- 他のInputStreamと組み合わせて使う:
FileInputStreamやByteArrayInputStreamと一緒に使うことが多いです。
7. ファイル操作は安全性と効率性の両立が大切
Javaでファイルを扱う際には、単にデータを読み書きするだけでなく、メモリ管理やエラー処理なども考慮する必要があります。BufferedInputStreamはパフォーマンスを向上させてくれますが、使い終わったら確実にcloseメソッドでリソースを解放することがとても重要です。
try-with-resources構文を活用すれば、コードを短くシンプルに保ちながら、安全性も高めることができます。Java初心者のうちは意識的にcloseメソッドの重要性を理解しておきましょう。