了解 Ruby 和 OS I/O 缓冲 [英] Understanding Ruby and OS I/O buffering
问题描述
IO 缓冲在 Ruby 中是如何工作的?使用 IO
和 File
类时,数据多久刷新到底层流?这与操作系统缓冲相比如何?需要做些什么来保证给定的数据已写入磁盘,然后才能自信地将其读回进行处理?
How does IO buffering work in Ruby? How often is data flushed to the underlying stream when using the IO
and File
classes? How does this compare to OS buffering? What needs to be done to guarantee that given data has been written to disk, before confidently reading it back for processing?
推荐答案
Ruby IO 文档并不是 100% 清楚说明这种缓冲是如何工作的,但您可以从文档中提取以下内容:
The Ruby IO documentation is not 100% clear on how this buffering works, but this is what you can extract from the documentation:
- 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()
调用.
IO.flush
: FlushesIO
. I also looked at the Ruby source and a call toIO.flush
also calls the underlying OSfflush()
. This should be enough to get the file cached, but does not guarantee physical data to disk.IO.sync=
: If set totrue
, no Ruby internal buffering is done. Everything is immidiately sent to the OS, andfflush()
is called for each write.IO.sync
: Returns the current sync setting (true
orfalse
).IO.fsync
: Flushes both the Ruby buffers + callsfsync()
on the OS (if it supports it). This will guarantee a full flush all the way to the physical disk file.IO.close
: Closes the RubyIO
and writes pending data to the OS. Note that this does not implyfsync()
. The POSIX documentation onclose()
says that it does NOT guarantee data is physically written to the file. So you need to use an explicitfsync()
call for that.
结论:flush
和/或 close
应该足以缓存文件,以便其他进程或操作可以完全读取它.为了确定地将文件一路传送到物理媒体,您需要调用IO.fsync
.
Conclusion: flush
and/or close
should be enough to get the file cached so that it can be read fully by another process or operation. To get the file all the way to the physical media with certainty, you need to call IO.fsync
.
其他相关方法:
IO.syswrite
:绕过 Ruby 内部缓冲区并执行一个直接的操作系统write
.如果您使用它,请不要将其与IO.read/write
混合使用.IO.sysread
:同上,但对于阅读.
IO.syswrite
: Bypass Ruby internal buffers and do a straight OSwrite
. If you use this then do not mix it withIO.read/write
.IO.sysread
: Same as above, but for reading.
这篇关于了解 Ruby 和 OS I/O 缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!