加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby:从Windows上的外部进程的stdout和stderr读取大数据

发布时间:2020-12-17 02:51:47 所属栏目:百科 来源:网络整理
导读:问候,所有, 我需要从Windows上的Ruby 1.9.2运行一个可能长时间运行的进程,然后从外部进程的标准输出和错误中捕获和解析数据.可以向每个数据发送大量数据,但我一次只对一行感兴趣(不捕获和存储整个输出). 经过一番研究后,我发现Open3 class将负责执行该过程并
问候,所有,

我需要从Windows上的Ruby 1.9.2运行一个可能长时间运行的进程,然后从外部进程的标准输出和错误中捕获和解析数据.可以向每个数据发送大量数据,但我一次只对一行感兴趣(不捕获和存储整个输出).

经过一番研究后,我发现Open3 class将负责执行该过程并给我IO对象连接到过程的标准输出和错误(通过popen3).

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

但是,我不确定如何在不阻止程序的情况下连续读取两个流.由于在发送大量数据时调用IO#readlines on out或err导致内存分配错误,我正在尝试连续检查两个流以获取可用输入,但是我的任何实现都没有太多运气.

提前感谢任何建议!

解决方法

经过大量不同的试验和错误尝试后,我最终想出了使用两个线程,一个从每个流中读取(generator.rb只是我编写的一个脚本,用于输出标准输出和错误):

require 'open3'

data = {}

Open3.popen3("ruby generator.rb") do |stdin,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]

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读