2009-08-09 12 views
2

Groovyには素晴らしいプロセス実行エンジンがあり、私はそれを使いたいと思います。
すべての必要な作業を行うメソッドconsumeProcessOutputがあります。しかし、私が望むのは、consumeProcessOutputappendまたは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)を追加してください。

これまでのところ、エラー出力が通常の出力と非常に高速になる場合にはうまくいかないソリューションが1つしかありません。

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ソリューションに同意します。しかし、私はグルーヴィーの方がよりエレガントでなければならないと考える傾向があります。

答えて

1

Groovyがprocess.inとprocess.errから読み込み、process.outに書き込むという慣習が気に入らない。 Javadocsの方がはっきりしているはずです。 エラーの出力がの2種類で、の出力がのように見えます。

プロセスのstdoutとstderrが単一の出力文字列に多重化されているので、個々の行が文字化けする可能性があります。 同期化キーワードをクロージャで使用できるとは思わないので、以下のコードに似たようなことをしますが、ロック機構を使用するか、おそらくsynchronizedメソッドでアウトラインクロージャをラップします。

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と同じ結果を出力しません。 –

関連する問題