2009-05-31 56 views
13

我正在寻找在Ruby中的方法基本上是这样的:是否有一个简单的方法来检查Ruby IO实例是否会在read()上阻塞?

可用
io.ready_for_read? 

我只是想检查是否一个给定的IO对象(在我的情况下,popen调用的结果)的输出,即跟进电话io.read(1)不会阻止。

这是两个选择我明白了,这两者都不喜欢:

  1. io.read_nonblock - 太薄的Unix read()的抽象 - 我不想处理errno错误处理。

  2. io.select带有超时0 - 模糊了这个简单操作的目的。

有没有更好的选择,我忽略了?

+0

我不/认为/如此。这真的是选择的目的。是的,选择有可怕的语法,但我想在理论上你可以修改一个“ready_for_read?”。将类型方法转换为使用select的IO。 – 2009-05-31 16:17:24

+0

`IO#ready_for_read?`实现不适用于我 - 它总是返回true。我认为问题在于`IO#select`阻塞,直到流被打开以供其他进程写入(在我的情况下它总是已经存在),直到有实际的数据被读取。我试图找到另一种方式来实现这一点,但我没有太多的运气。 – 2009-08-28 13:51:37

回答

7

有点晚了,但如果你require 'io/wait',你可以使用ready?验证IO可以无阻塞地读取的。当然,取决于你打算阅读的内容(以及你打算如何做)你的IO对象可能仍然阻塞,但这应该有所帮助。我不确定这个库是否在所有平台上都受支持,而且我也不知道为什么这个功能与IO库的其余部分分离。查看更多这里:http://ruby-doc.org/stdlib/libdoc/io/wait/rdoc/

6

我已经准备好了,没有,没有简单的方法来做到这一点。每彼得库珀的建议,这里是IO#ready_for_read?

class IO 
    def ready_for_read? 
    result = IO.select([self], nil, nil, 0) 
    result && (result.first.first == self) 
    end 
end 
0

在Windows上,我看到一些与IO/wait不一致。红宝石我现在这里是:

红宝石1.9.2p136(2010-12-25)[I386-的mingw32]

在这一个既NREAD准备好了吗?已实施,但它们返回错误的结果。在我正在使用的另一版本准备好了吗?仍然被打破,nread甚至不存在。

一种可能性是使用io.stat.size,它告诉您可以在IO流中读取的字节数。 http://www.ruby-doc.org/core/classes/File/Stat.html

文档建议它用于文件,但我在连接到单独进程的管道上使用它(通过Ruby的Open3.popen3)。到目前为止,它对我来说很有用。

相关问题