我试图以非阻塞的方式从io读取一行。红宝石非阻塞行读取
不幸的是readline
块。我想我可以用来解决这个问题,在这里我存储了部分结果,检查缓冲区中是否有多行等等,但是对于这样一个简单的任务来说似乎有点复杂。有一个更好的方法吗?
注:我使用的事件多路(select
),我与它很高兴,我不想来创建线程,使用EventMachine的,等等
我试图以非阻塞的方式从io读取一行。红宝石非阻塞行读取
不幸的是readline
块。我想我可以用来解决这个问题,在这里我存储了部分结果,检查缓冲区中是否有多行等等,但是对于这样一个简单的任务来说似乎有点复杂。有一个更好的方法吗?
注:我使用的事件多路(select
),我与它很高兴,我不想来创建线程,使用EventMachine的,等等
我认为read_nonblock解决方案可能是要走的路。很简单,不是最高效的猴子补丁版本:
class IO
def readline_nonblock
rlnb_buffer = ""
while ch = self.read_nonblock(1)
rlnb_buffer << ch
if ch == "\n" then
result = rlnb_buffer
return result
end
end
end
end
抛出一个异常,如果没有数据准备好了,就像read_nonblock,所以你要救的是只得到一个零背部等
此实现通过不丢弃数据读取不以换行符结束对马克·里德的回答改进:
class IO
def readline_nonblock
buffer = ""
buffer << read_nonblock(1) while buffer[-1] != "\n"
buffer
rescue IO::WaitReadable => blocking
raise blocking if buffer.empty?
buffer
end
end
“不保证” - 这有点吓人。不要依赖不确定的“特征”。 “我测试了这个” - 真的吗?用不同的输入法?它可能只工作,因为你的输入是行缓冲... – 2014-01-02 17:26:18
我还没有足够的勇气来依靠它,这就是为什么我包括第二部分。 :-) – 2014-01-02 21:09:20
我验证了'read_nonblock(4096)'在ruby 1.9.3,2.0.0和2.1.3上没有返回单行。最好把这个建议拿出来。很容易用'ruby19 -e'x = IO.popen(“cat/etc/fstab”)来验证;睡觉0.2; p x.read_nonblock(4096)''。 – chutz 2014-10-06 13:47:53
是啊,那是我最初的想法,而这正是我终于做到了,但我看像我可以(不只是一个字符),我认为这对性能更好。感谢monke-patch提示;) – 2012-09-21 15:39:29