【问题标题】:Understanding Ruby and OS I/O buffering了解 Ruby 和 OS I/O 缓冲
【发布时间】:2011-10-05 18:40:33
【问题描述】:

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

【问题讨论】:

    标签: ruby operating-system io buffering io-buffering


    【解决方案1】:

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

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

    相关方法看:

    • IO.flush:刷新IO。我还查看了 Ruby 源代码,对IO.flush 的调用也调用了底层操作系统fflush()。这应该足以缓存文件,但不能保证物理数据到磁盘。
    • IO.sync=:如果设置为true,则不会进行 Ruby 内部缓冲。所有内容都会立即发送到操作系统,每次写入都会调用fflush()
    • IO.sync:返回当前同步设置(truefalse)。
    • 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:和上面一样,只是为了阅读。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2014-09-20
        • 2015-07-05
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        相关资源
        最近更新 更多