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的一个必须更优雅。
答案 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");