32

IO 缓冲在 Ruby 中是如何工作的?IO使用andFile类时,数据多久刷新一次到底层流?这与操作系统缓冲相比如何?需要做些什么来保证给定的数据已经写入磁盘,然后才能自信地读回进行处理?

4

2 回答 2

57

Ruby IO 文档并没有 100% 清楚地说明这种缓冲是如何工作的,但这是您可以从文档中提取的内容:

  • Ruby IO 有自己的内部缓冲区
  • 除此之外,底层操作系统可能会或可能不会进一步缓冲数据。

相关方法查看:

  • IO.flush: 冲洗IO。我还查看了 Ruby 源代码和对IO.flush也调用底层 OS的调用fflush()。这应该足以缓存文件,但不能保证物理数据到磁盘。
  • IO.sync=: 如果设置为true,则不进行 Ruby 内部缓冲。一切都立即发送到操作系统,并fflush()在每次写入时调用。
  • IO.sync:返回当前同步设置(truefalse)。
  • IO.fsync:刷新fsync()操作系统上的 Ruby 缓冲区 + 调用(如果它支持的话)。这将保证完全刷新到物理磁盘文件。
  • IO.close: 关闭 RubyIO并将挂起的数据写入操作系统。请注意,这并不意味着fsync(). POSIX 文档close()说它不保证数据被物理写入文件。因此,您需要为此使用显式fsync()调用。

结论:flush和/或close应该足以缓存文件,以便其他进程或操作可以完全读取它。要确保将文件一直传输到物理媒体,您需要调用IO.fsync.

其他相关方法:

  • IO.syswrite: 绕过 Ruby 内部缓冲区,做一个直接的操作系统write。如果您使用它,请不要将其与IO.read/write.
  • IO.sysread: 同上,只是为了阅读。
于 2011-07-15T00:16:37.030 回答
3

Ruby 在操作系统之上进行内部缓冲。当您执行 file.flush 时,Ruby 会刷新其内部缓冲区。为确保将文件写入磁盘,您需要执行 file.fsync。但最终你不能确定文件是否写入磁盘,这取决于操作系统、硬盘控制器和硬盘。

于 2011-07-15T01:46:41.810 回答