问候,所有,
我需要从Windows上的Ruby 1.9.2运行一个可能长时间运行的进程,然后从外部进程的标准输出和错误中捕获和解析数据.可以向每个数据发送大量数据,但我一次只对一行感兴趣(不捕获和存储整个输出).
经过一些研究后,我发现Open3类将负责执行该过程,并为我提供IO连接到进程标准输出和错误的对象(通过popen3).
Open3.popen3("external-program.bat") do |stdin, out, err, thread|
# Step3.profit() ?
end
Run Code Online (Sandbox Code Playgroud)
但是,我不确定如何在不阻止程序的情况下连续读取两个流.由于呼吁IO#readlines对out或者err当大量的数据已在内存分配错误被送往结果,我想继续检查可用输入两个流,但没有任何我实现多少运气.
提前感谢任何建议!
在经过大量不同的尝试和错误尝试之后,我最终想出了使用两个线程,一个从每个流中读取(generator.rb只是我写的一个脚本,用于输出标准输出和错误):
require 'open3'
data = {}
Open3.popen3("ruby generator.rb") do |stdin, out, err, external|
# Create a thread to read from each stream
{ :out => out, :err => err }.each do |key, stream|
Thread.new do
until (line = stream.gets).nil? do
data[key] = line
end
end
end
# Don't exit until the external process is done
external.join
end
puts data[:out]
puts data[:err]
Run Code Online (Sandbox Code Playgroud)
它只是输出发送到标准输出的最后一行和调用程序的错误,但显然可以扩展为进行额外的处理(每个线程中有不同的逻辑).在我最终提出这个问题之前我使用的一种方法是由于竞争条件而导致一些失败; 我不知道这段代码是否仍然容易受到攻击,但我还没有遇到类似的失败.