• ベストアンサー

HDDへの書き込みはどのように行われますか?

HDDの書き込み時に、セクタサイズ未満、あるいはクラスタサイズ未満の書き込みはどのように実行されるのでしょうか? 例えば、512バイト(1セクタ分)のデータの、奇数バイト目(256ヶ所)にだけデータを上書きしていく場合、「セクタを読み出して、1バイト上書きして書き戻し」という操作が256回行われるのでしょうか? もしそうだとすると、プログラマが何も工夫しなければ、たった256バイトの書き込みのために、R/Wあわせて512回ものディスクアクセスが生じてしまうことになりますよね? それとも同一セクタやクラスタに連続して行われる書き込みは、OSやランタイムのバッファで自動的にまとめてくれるのでしょうか? またこの場合、どういう方法でまとめてくれるのでしょうか? ご教授よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.2

「512バイト(1セクタ分)のデータの、奇数バイト目(256ヶ所)にだけデータを上書きしていく」をプログラムでどう実現するかを考えましょう。 ストリーム入出力だと基本的に頭から順に書いていくことしかできませんよね。書き換えない偶数バイト目も読んで書かないと意図する通りにならないでしょう。 あるいは"r+b"で開いてfseekを駆使する? これはライブラリのバッファリングが前提となるでしょう。 通常、OSレベルではファイルへの読み書きはセクタやクラスタの単位で実施されます。1バイト書き込むときはライブラリ内でセクタあるいはクラスタ単位にして書き込みます。バッファリングを禁止するような設定のときは本当に256回(書き込みバッファリングを禁止)や512回(読み書きともバッファリング禁止)のディスク操作を実行することになります。 # 読み書きともバッファリング禁止する機能は多分ないけど ストリームじゃなくmmapしてランダムアクセスということも可能ですが、この場合はページ単位でメモリ上にバッファリングされ適当なタイミングでディスクに反映するので、毎回msyncを呼び出さなければディスクへの書き込みは1,2回にまとめられるでしょう。 # ある程度時間がたってページが変わっていればディスクに反映する手法です

minimax2005
質問者

お礼

回答ありがとうございます。 確かにいろいろと実現方法がありますね。 おかげさまで理解が深まりました。

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.1

一般論で言うと、ファイルに対しての部分的な書き込みであれば、OSがバッファリングします。 OSのシステムコールでなく言語のライブラリを使って書き込むとさらにライブラリがバッファリングしているかもしれません。 ファイルに対してでなく、直接デバイスドライバを呼び出して書き込むのなら、そもそもセクタ単位でしか書き込めないので、「奇数バイトだけ書き込みたい」というのをどうやって実現するかはプログラマ側で考えることになります。

minimax2005
質問者

お礼

回答ありがとうございます。 バッファリングするときに、どのようにして同一セクタ内への複数の書き込みをまとめているのでしょうか? 「奇数バイト目だけ書き込む」時には、偶数バイト目に書き込むべきデータは持っていないので、セクタ内での書き込み位置を記録して、そのことを覚えておかなければならないと思います。 セクタごとにダーティビットのビットマップをもつなどして実装できると思うのですが、「同一セクタ内に複数回書き込む」というレアケースのためにこのような実装がされているのかどうかが、自分はちょっと疑問であります。

minimax2005
質問者

補足

よく考えたら、 ランタイムのバッファは偶数バイト目の書き込みデータを持っていないけれど、 OSのバッファキャッシュは、1回目に1バイト書き込むときに読みだしたセクタをキャッシュしているので、このデータに上書きしていけば、セクタ内の位置を記録することなくバッファリングできますね。

関連するQ&A