2011-01-11 70 views
4

问候,所有从stdout和外部进程的标准错误大的数据,红宝石:阅读在Windows

我需要在Windows上运行,从红宝石1.9.2潜在的长期运行的进程,并随后捕获和分析数据来自外部过程的标准输出和错误。大量的数据可以发送给每个数据,但是我一次只对一行感兴趣(不捕获和存储整个输出)。

了一些研究之后,我发现Open3 class将采取执行过程,并给了我(通过popen3)连接到进程的标准输出和错误IO对象的照顾。

Open3.popen3("external-program.bat") do |stdin, out, err, thread| 
    # Step3.profit() ? 
end 

但是,我不知道如何在不阻止程序的情况下连续读取两个流。由于outerr上调用IO#readlines当大量数据已发送导致内存分配错误,我试图不断检查两个流的可用输入,但没有太多的运气与我的任何实现。

在此先感谢您的任何建议!

+0

你能指定Ruby的版本吗? Open3在1.8.7中被破解,并且需要win32-open3 gem代替 – 2011-01-11 19:15:02

回答

8

了很多不同的尝试和错误的尝试之后,我终于想出了使用两个线程,一个从每个流中读取(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] 

它只是输出最后一行发送到标准输出和错误的调用程序,但显然可以扩展做额外的处理(在每个线程中有不同的逻辑)。我在之前使用的方法我终于想出了这个问题,导致一些由于竞态条件而导致的失败;我不知道这段代码是否仍然脆弱,但我还没有遇到类似的失败。