ショートカット
ファシリテーター × あり方
コーディングの向こう側
Hello, ANOTHER world!
オブジェクト指向のはなし
プログラミングのはなし
C言語実力診断クイズ
eSkillBooks
Hello, ANOTHER world!

バッファについて

ストリームには必ず送り出す側と受け取る側があります。標準出力ストリームなら "Hello, world" のようなプログラムがデータを送り出し、画面に文字を表示するプログラムが受け取ります。入力ファイルストリームならファイルから送られたデータが入力を実行するプログラムに受け取られます。
ストリームにデータを送り出すとき、出口ではデータを受信する何かがスタンバイしている必要があります。標準出力ストリームなら、画面に文字を表示するためのプログラムがデータの受け皿になっていて、受け取ったデータを表示しています。
さて、ストリームにデータを入れたとき、受け取る側の準備ができていなかったらどうなってしまうでしょう?
実際、いつもデータを受け取るプログラムが準備万端とは限りません。特に、ファイルやネットワークなどのようなハードウェアの状態に依存するストリームの場合は待ち時間が発生するのが普通です(ハードディスクの磁気ヘッドが移動するのを待ったり、通信先の準備ができるのを待ったりする必要があります)。もし待ち時間中にストリームにデータを入れたら、データが「こぼれて」しまいます。
かと言って、受信側の状態を常に意識しながらストリームを操作するのでは実用に耐えません。そこで、ストリームの途中には「バッファ(buffer)」と呼ばれる仕組みが作ってあります。
"buffer" は「緩衝剤」という意味の英語ですが、その名の通り、データを一時的に吸収するダムのような働きをします。入り口から入ってきたデータを一時的に蓄えて、出口の準備ができたときに通すようにします。
これで、ストリームにデータを送り出す側も、ストリームからデータを取り出す側も、互いに相手の都合と関係なく好きなタイミングで処理できるようになります。
バッファにはもう一つ重要な利点があります。速度の向上です。
ファイルストリームの場合を考えてみましょう。ファイルは通常ハードディスクなどの記憶装置に作られます。これらの記憶装置の動作速度はメモリよりもだいぶ遅いので、頻繁にアクセスすると動作が遅くなってしまいます。とくに、小さなサイズのデータを細かく読み書きすると非常に遅くなります。そこで、小さなデータはある程度まとめておいて、大きな塊になってから一度に処理するのが良いということになります。
これをバッファが可能にします。バッファはメモリ上にあるので、直接ハードディスクとやりとりするよりも、バッファを使って間接的にやりとりする方が速くなるのです。出力ファイルストリームでは、書き出すデータをバッファにためておき、ある程度の大きさになったところで一気にハードディスクに書き込んでいます。入力ファイルストリームでは、ハードディスクからデータを読み込むときに多めに読んでバッファにためておき、その後しばらくの読み込みではバッファとのやりとりだけですませるようになっています。
ときどきバッファが邪魔になることもあります。ストリームに入れたデータを今すぐ出口にまで届けたいときがそうです。例えばプログラムの動作状況をログファイルに細かく記録しているような場合、突然システムがクラッシュしても処理がどこまで進んだかを後でログファイルを見ればわかるようにするためには、バッファが邪魔です。クラッシュするとバッファの中身が失われるので、書き込んだつもりのデータがまだファイルに書かれていないということになるからです。そういうときは、バッファを「フラッシュ(flush)」します。
"flush" は「水をどっと流す」という意味です(よく水洗トイレのレバーに書いてありますね)。バッファをフラッシュするというのは、バッファの中にたまっているデータを全部吐き出すという意味です。この操作によって、データがただちにストリームの出口まで送られます。
なお、ファイルをクローズするときには自動的にフラッシュされます。ですから、とくにバッファを空にするタイミングを制御したいとき以外は意識的にフラッシュする必要はありません。標準的な関数は、細かいことを気にせず使えるようにうまくできているのです。

("Hello, ANOTHER world!" は2001年11月から2002年11月にかけて作成されたコンテンツです。)