Groovy / Java进程管理拦截/监听输出

时间:2009-08-09 20:34:36

标签: java groovy

Groovy有一个很好的流程执行引擎,我想使用它 有一种方法consumeProcessOutput可以完成所有必要的工作。但我想要的是每次consumeProcessOutput调用append out 实例上的某些内容时注入我的其他功能。

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 个答案:

答案 0 :(得分:1)

我不喜欢Groovy使用从process.in和process.err读取并写入process.out的约定。 Javadocs应该更清楚。似乎错误 out 将是两种类型,而 则是奇怪的。

由于您正在将进程'stdout和stderr多路复用到单个输出字符串中,因此您认为各行可能会出现乱码。我不相信您可以将 synchronized 关键字与闭包一起使用,因此可能会执行类似于下面的代码但使用锁定机制或者可能使用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");