【发布时间】:2011-10-05 18:40:33
【问题描述】:
IO 缓冲在 Ruby 中是如何工作的?使用IO 和File 类时,数据多久刷新一次到底层流?这与操作系统缓冲相比如何?需要做些什么来保证给定数据已写入磁盘,然后才能放心地读回以进行处理?
【问题讨论】:
标签: ruby operating-system io buffering io-buffering
IO 缓冲在 Ruby 中是如何工作的?使用IO 和File 类时,数据多久刷新一次到底层流?这与操作系统缓冲相比如何?需要做些什么来保证给定数据已写入磁盘,然后才能放心地读回以进行处理?
【问题讨论】:
标签: ruby operating-system io buffering io-buffering
Ruby IO 文档并没有 100% 清楚地说明这种缓冲的工作原理,但这是您可以从文档中提取的内容:
相关方法看:
IO.flush:刷新IO。我还查看了 Ruby 源代码,对IO.flush 的调用也调用了底层操作系统fflush()。这应该足以缓存文件,但不能保证物理数据到磁盘。IO.sync=:如果设置为true,则不会进行 Ruby 内部缓冲。所有内容都会立即发送到操作系统,每次写入都会调用fflush()。IO.sync:返回当前同步设置(true 或 false)。IO.fsync:在操作系统上刷新 Ruby 缓冲区 + 调用 fsync()(如果它支持的话)。这将保证完全刷新到物理磁盘文件。IO.close:关闭 Ruby IO 并将挂起的数据写入操作系统。请注意,这并不意味着fsync()。 close() 上的 POSIX 文档说它不保证数据被物理写入文件。因此,您需要为此使用明确的 fsync() 调用。结论:flush 和/或close 应该足以缓存文件,以便其他进程或操作可以完全读取它。要确保将文件一直传输到物理媒体,您需要致电IO.fsync。
其他相关方法:
IO.syswrite:绕过 Ruby 内部缓冲区并直接执行操作系统 write。如果您使用它,请不要将其与 IO.read/write 混合使用。IO.sysread:和上面一样,只是为了阅读。【讨论】:
Ruby 在操作系统之上进行内部缓冲。当您执行 file.flush 时,Ruby 会刷新其内部缓冲区。为确保将文件写入磁盘,您需要执行 file.fsync。但最终你不能确定文件是否写入磁盘,这取决于操作系统、硬盘控制器和硬盘。
【讨论】: