2011-01-11 64 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] 

它只是輸出最後一行發送到標準輸出和錯誤的調用程序,但顯然可以擴展做額外的處理(在每個線程中有不同的邏輯)。我在之前使用的方法我終於想出了這個問題,導致一些由於競態條件而導致的失敗;我不知道這段代碼是否仍然脆弱,但我還沒有遇到類似的失敗。