web-dev-qa-db-ja.com

RubyおよびOSI / Oバッファリングを理解する

IOバッファリングはRubyでどのように機能しますか?IOおよびFileクラスを使用する場合、データはどのくらいの頻度で基になるストリームにフラッシュされますか?これはOSと比較してどうですか?バッファリング?処理のために自信を持って読み戻す前に、特定のデータがディスクに書き込まれたことを保証するために何をする必要がありますか?

30
jrdioko

Ruby IOドキュメントは、このバッファリングがどのように機能するかについて100%明確ではありませんが、これはドキュメントから抽出できるものです。

  • Ruby IOには独自の内部バッファーがあります
  • それに加えて、基盤となるオペレーティングシステムは、データをさらにバッファリングする場合としない場合があります。

関連する方法:

  • _IO.flush_IOをフラッシュします。また、Rubyソースを調べ、_IO.flush_を呼び出すと、基盤となるOS fflush() も呼び出されます。これでファイルをキャッシュできますが、ディスクへの物理データを保証するものではありません。
  • _IO.sync=_trueに設定すると、Ruby内部バッファリングは行われません。すべてがすぐにOSに送信され、fflush()は書き込みごとに呼び出されます。
  • _IO.sync_ :現在の同期設定(trueまたはfalse)を返します。
  • _IO.fsync_ :OS上のRubyバッファ+呼び出し fsync() の両方をフラッシュします(サポートしている場合)。これにより、物理ディスクファイルまで完全にフラッシュします。
  • _IO.close_ :Ruby IOを閉じ、保留中のデータをOSに書き込みます。これはfsync()を意味しないことに注意してください。POSIXドキュメントon close() は、データがファイルに物理的に書き込まれることを保証しないことを示しています。そのため、明示的なfsync()呼び出しを使用する必要があります。

結論:flushおよび/またはcloseは、ファイルをキャッシュして、別のプロセスまたは操作で完全に読み取ることができるようにするのに十分なはずです。ファイルを確実に物理メディアに到達させるには、_IO.fsync_を呼び出す必要があります。

その他の関連する方法:

  • _IO.syswrite_ :Ruby内部バッファをバイパスし、ストレートOS writeを実行します。これを使用する場合は、_IO.read/write_。
  • _IO.sysread_ :上記と同じですが、読み取り用です。
55
Casper

RubyはOS上で内部バッファリングを行います。 file.flush Rubyは、その内部バッファーをフラッシュします。ファイルがディスクに書き込まれるようにするには、file.fsyncを実行する必要があります。しかし、最終的には、ファイルが書き込まれるかどうかを確認できません。とにかくディスクに、それはOS、hddコントローラーとhddに依存します。

2
Björn Nilsson