JavaのBufferedOutputStreamクラスの使い方を解説!flushメソッドでデータを確実に出力しよう
生徒
「Javaでファイルに書き込む処理って、書いた内容がすぐに保存されるんですか?」
先生
「それが、すぐには保存されないこともあるんです。バッファにたまっているだけで、実際のファイルに書き込まれていない場合があります。」
生徒
「えっ、それって困りませんか?書いたのに消えちゃうとか…」
先生
「そこで使うのがBufferedOutputStreamのflushメソッドです。これを使えば、バッファにたまっているデータをすぐに出力先へ書き出せるんですよ。今日はこの使い方を学びましょう!」
1. BufferedOutputStreamクラスとは
BufferedOutputStreamは、Javaでデータを書き込むときに使う出力用ストリームのひとつで、バッファを使って処理の効率を高める仕組みを持っています。
ファイルなどにデータを書き込むとき、1バイトずつ直接書くと効率が悪くなります。BufferedOutputStreamは、データをいったんバッファにためてからまとめて書き込むことで、出力処理の速度を改善してくれます。
2. flushメソッドとは?
flushメソッドは、BufferedOutputStreamなどの出力ストリームで使われるメソッドで、「バッファにたまっているデータをすぐに書き出す」ために使います。
たとえば、バッファがいっぱいになる前にプログラムが終了した場合、flushを使っていないと、書き込み内容が出力先(ファイルなど)に保存されないまま終わってしまう可能性があります。flushは「確実に保存する」ための重要な操作です。
3. flushメソッドの基本的な使い方
それでは、実際にBufferedOutputStreamでファイルに文字列を書き込んで、flushで内容を出力する基本的なサンプルを見てみましょう。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlushExample {
public static void main(String[] args) {
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
String message = "こんにちは、Java!";
bos.write(message.getBytes()); // バッファに書き込み
bos.flush(); // バッファの内容をファイルに出力
} catch (IOException e) {
e.printStackTrace();
}
}
}
output.txt に「こんにちは、Java!」という内容が保存される
このようにwriteメソッドで書き込んだあと、flushメソッドを呼び出すことで、データが実際にファイルへ書き出されます。
4. flushが必要な理由
なぜflushが必要なのかというと、BufferedOutputStreamは性能を上げるために「すぐに書き出さずにためておく」仕組みになっているからです。バッファサイズを超えるまで書き出しを遅らせるので、少量のデータだけを書いたまま終了すると、ファイルに書き込まれないまま終わることがあります。
そのため、書き込みが完了したら必ずflushを呼ぶようにするのが安全な書き方です。
5. flushとcloseの違い
flushメソッドは「バッファの中身を出力先へ書き出す」だけですが、closeメソッドは「書き出してからストリームを閉じる」操作です。
closeを呼べば内部的にflushも実行されますが、ストリームを閉じたあとに再利用することはできません。逆にflushだけであれば、書き出したあとも引き続きwriteを使ってデータを書き込むことができます。
6. flushはこんな場面で便利!
flushメソッドは次のような場面で活躍します。
- プログラムの途中で何度もバッファの内容を保存したいとき
- 重要なログやメッセージを即座にファイルへ書き出したいとき
- 書き込み後すぐに他のプロセスでファイルを読み取る必要があるとき
たとえばログ出力では、flushを使っておかないとログが残らず、問題発生時に原因調査ができなくなることがあります。
7. BufferedOutputStreamとflushを安全に使うには?
flushを使っていても、ストリームを確実に閉じることはとても重要です。Java7以降では、try-with-resources構文を使えば自動的にcloseが呼ばれ、flushも確実に実行されます。
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("data.txt"))) {
bos.write("データ".getBytes());
// flushは不要でもclose時に自動で実行される
}
このようにしておけば、flushの呼び忘れによるデータ損失を防ぐことができます。
まとめ
BufferedOutputStreamとflushメソッドの重要ポイント総整理
本記事では、Javaにおけるファイル出力処理の中でも特に重要なBufferedOutputStreamクラスと、
その中核となるflushメソッドの役割や使い方について詳しく解説してきました。
Javaでのファイル書き込みは一見すると単純な処理に見えますが、
実際には「バッファ」という仕組みが介在しており、その理解が不十分だと
「書いたはずのデータが保存されていない」「途中までしか出力されていない」
といったトラブルにつながることがあります。
BufferedOutputStreamは、出力処理のパフォーマンスを高めるために、
データを一時的にメモリ上のバッファにためてからまとめて書き出す仕組みを持っています。
この仕組みによって、ディスクアクセス回数が減り、処理速度が向上します。
しかしその反面、バッファに残ったデータは、明示的に書き出さない限り
ファイルへ反映されないという特徴もあります。
flushメソッドが果たす役割
そこで重要になるのがflushメソッドです。
flushは、バッファ内にたまっているデータを
強制的に出力先へ書き出すためのメソッドであり、
「今この時点までのデータを確実に保存したい」という場面で欠かせません。
特に、ログファイルの出力や、途中経過を他のプログラムから参照する必要がある場合には、
flushを適切に使うことで信頼性の高いプログラムを作ることができます。
また、flushとcloseの違いを正しく理解することも重要です。
closeはストリームを閉じる際に内部でflushを実行しますが、
一度閉じたストリームは再利用できません。
そのため、処理の途中で何度も書き込みを続けたい場合は、
flushを使ってバッファを出力しつつ、
ストリーム自体は開いたままにしておく、という使い分けが必要になります。
安全で実務的な書き方のポイント
実務や学習の現場では、try-with-resources構文を活用することで、
ストリームのクローズ忘れを防ぎ、安全性を高めることができます。
この構文を使えば、例外が発生した場合でも自動的にcloseが呼ばれ、
結果としてflushも確実に実行されます。
初心者のうちは特に、この書き方を基本形として身につけておくと安心です。
まとめとして押さえておきたい要点
- BufferedOutputStreamはバッファを使って出力処理を高速化する
- flushはバッファ内のデータを即座に出力するための重要なメソッド
- flushを呼ばないと、書き込み内容が保存されない場合がある
- closeはflushを含むが、ストリームは再利用できなくなる
- try-with-resourcesを使うことで安全な出力処理が実現できる
まとめとしてのサンプルプログラム
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedOutputSummary {
public static void main(String[] args) {
try (BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("summary.txt"))) {
bos.write("BufferedOutputStreamの理解が深まりました".getBytes());
bos.flush(); // ここで確実にファイルへ書き出す
} catch (IOException e) {
e.printStackTrace();
}
}
}
上記のように、writeでデータを書き込み、
必要に応じてflushを呼ぶことで、
データの欠落を防ぎながら効率的なファイル出力が可能になります。
生徒
「BufferedOutputStreamって、速くなるだけじゃなくて、 flushをちゃんと使わないと危ないこともあるんですね」
先生
「そうですね。バッファは便利ですが、仕組みを理解していないと 思わぬデータ消失につながることがあります」
生徒
「これからは、ファイルに書き込む処理では flushやcloseを意識してコードを書くようにします」
先生
「それが大切です。Javaの入出力処理は、 基本を丁寧に押さえることで、実務でも安心して使えるようになりますよ」