有没有一种简单的方法来检查 Ruby IO 实例是否会在 read() 上阻塞?
-
06-09-2019 - |
题
我正在寻找 Ruby 中的一种方法,基本上是这样的:
io.ready_for_read?
我只想检查是否给定 IO
对象(在我的例子中,结果是 popen
调用)有可用的输出,即跟进电话 io.read(1)
不会阻塞。
这是我看到的两个选项,我都不喜欢:
io.read_nonblock
- Unix 的抽象太薄弱read()
——我不想应付errno
错误处理。io.select
超时为 0 —— 混淆了这个简单操作的目的。
有没有我忽略的更好的选择?
解决方案
有点晚了,但如果你 require 'io/wait'
, , 您可以使用 ready?
验证IO是否可以无阻塞地读取。当然,根据您打算读取的数量(以及您计划如何执行),您的 IO 对象可能仍然会阻塞,但这应该会有所帮助。我不确定这个库是否在所有平台上都受支持,而且我也不知道为什么这个功能与 IO 库的其余部分分开。在这里查看更多内容: http://ruby-doc.org/stdlib/libdoc/io/wait/rdoc/
其他提示
我准备得出结论:不,没有简单的方法可以做到这一点。根据彼得·库珀的建议,这里是 IO#ready_for_read?
:
class IO
def ready_for_read?
result = IO.select([self], nil, nil, 0)
result && (result.first.first == self)
end
end
在 Windows 上我发现了一些不一致的地方 IO/等待. 。我现在这里的红宝石是:
红宝石 1.9.2p136 (2010-12-25) [i386-mingw32]
就这一项而言 读 和 准备好? 已实现,但返回错误结果。在我使用的不同版本上 准备好? 仍然破碎并且 读 甚至不存在。
一种可能性是使用 io.stat.大小, ,它告诉您 IO 流中可读取的字节数。http://www.ruby-doc.org/core/classes/File/Stat.html
文档表明它用于文件,但我已经在连接到单独进程的管道上使用了它(通过 Ruby 的 Open3.popen3)。到目前为止它对我有用。