了解Ruby和OS I / O缓冲

IO缓冲如何在Ruby中工作? 使用IOFile类时,数据刷新到基础流的频率是多少? 这与OS缓冲相比如何? 需要做些什么来保证给定的数据写入磁盘,然后自信地将其读回处理?

关于缓冲如何工作,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内部缓冲区并执行直接的OS write 。 如果您使用它,请不要将其与IO.read/write混合使用。
  • IO.sysread :与上面相同,但是用于阅读。

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