2009-08-09 23 views
2

Groovy有一個很好的進程執行引擎,我想使用它。
有一種方法consumeProcessOutput可以完成所有必要的工作。但我要的是每次都注入我的附加功能時,consumeProcessOutput通話append或東西就out實例。Groovy/Java進程管理攔截/監聽輸出

public class ProcessExecutor { 
    static public void execute(IOutput output, String processName) { 
     def process = processName.execute() 

     def out = new StringBuffer() 
     process.consumeProcessOutput(out, out) 

     process.waitFor() 
    } 
} 

我知道

use (MyStringBufferIntercept) { 
    process.consumeProcessOutput(out, out) 
} 

但他們似乎只對當前線程工作,consumeProcessOutput創建額外的線程。

那麼有什麼解決方案聽線添加並呼籲output.addLine(line)output.addErrorLine(line)

到目前爲止,我只有一個解決方案時,錯誤輸出與正常輸出一起去相當快不工作好:訂單的變化。

def process = processName.execute() 

    def inThread = Thread.start { 
    process.in.eachLine{ line -> output.addLine(line)} 
    } 

    def errThread = Thread.start { 
    process.err.eachLine{ line -> output.addErrorLine(line)} 
    } 

    inThread.join() 
    errThread.join() 

    process.waitFor() 

我會同意Java解決方案。但我傾向於認爲groovy的人必須更優雅。

回答

1

我不喜歡Groovy使用從process.in和process.err讀取和寫入process.out公約。 Javadocs應該更清楚。這似乎是犯錯將是兩個種類,且在奇一出。

既然你是復進程的輸出和錯誤到您的單一輸出字符串,你是正確的,個別線路可能會出現亂碼。我不相信你可以使用同步關鍵字與閉包,所以也許做類似於下面的代碼的東西,但使用鎖定機制或可能包裝大綱閉包在同步方法。

class P { 
static public void execute(String processName) { 
    def process = processName.execute() 
    def output = new StringBuffer() 

    def outline = { line -> output += line + '\n' } 

def inThread = Thread.start { 
     process.in.eachLine{ outline it } 
    } 

def errThread = Thread.start { 
      process.err.eachLine{ outline it } 
    } 

     inThread.join() 
     errThread.join() 
     process.waitFor() 
     println output 
    } 
} 

def p = new P(); 
p.execute("ls -l"); 
+0

問題在於此解決方案行不會按照正確的順序進行。如果執行一些腳本過程,其中錯誤行在像斑馬線一樣的正常行之後,自定義解決方案將打印與consumeProcessOutput不同的結果。 – 2009-08-17 20:35:31