了解Ruby和OS I / O缓冲
IO缓冲如何在Ruby中工作? 使用IO
和File
类时,数据刷新到基础流的频率是多少? 这与OS缓冲相比如何? 需要做些什么来保证给定的数据写入磁盘,然后自信地将其读回处理?
关于缓冲如何工作,Ruby IO文档并非100%明确,但您可以从文档中提取:
- Ruby IO有自己的内部缓冲区
- 除此之外,底层操作系统可能会或可能不会进一步缓冲数据。
要看的相关方法:
-
IO.flush
:刷新IO
。 我还查看了Ruby源代码,对IO.flush
的调用也调用了底层操作系统fflush()
。 这应该足以使文件缓存,但不保证物理数据到磁盘。 -
IO.sync=
:如果设置为true
,则不执行Ruby内部缓冲。 所有内容都会立即发送到操作系统,每次写入都会调用fflush()
。 -
IO.sync
:返回当前的同步设置(true
或false
)。 -
IO.fsync
:刷新操作系统上的Ruby缓冲区+调用fsync()
(如果它支持)。 这将保证完全刷新到物理磁盘文件。 -
IO.close
:关闭RubyIO
并将待处理数据写入操作系统。 请注意,这并不意味着fsync()
。close()
上的POSIX文档说它不保证数据物理写入文件。 因此,您需要使用显式的fsync()
调用。
结论: flush
和/或close
应足以使文件缓存,以便其他进程或操作可以完全读取。 要确保将文件一直提供给物理介质,您需要调用IO.fsync
。
其他相关方法:
-
IO.syswrite
:绕过Ruby内部缓冲区并执行直接的OSwrite
。 如果您使用它,请不要将其与IO.read/write
混合使用。 -
IO.sysread
:与上面相同,但是用于阅读。
Ruby在操作系统之上进行内部缓冲。 当你执行file.flush时,Ruby会刷新其内部缓冲区。 要确保将文件写入磁盘,您需要执行file.fsync。 但最终你无法确定文件是否写入磁盘,它取决于操作系统,硬盘控制器和硬盘驱动器。