[英]Efficient execution and output stream redirection of process spawned with Runtime.exec()
我有一个脚本,可以多次执行一个程序,从而向STDERR和STDOUT产生约350行输出。 现在,我需要用Java执行脚本,从而将输出流打印到其原始目的地。 因此,基本上,我从Java类内部执行脚本,从而维护了用户的原始行为。
我这样做的方法是受类似建议的启发,例如从java Runtime.exec读取流,并且在功能上工作正常。
Process p = Runtime.getRuntime().exec(cmdarray);
new Thread(new ProcessInputStreamHandler(p.getInputStream(), System.out)).start();
new Thread(new ProcessInputStreamHandler(p.getErrorStream(), System.err)).start();
return p.waitFor();
和类ProcessInputStreamHandler
:
class ProcessInputStreamHandler implements Runnable {
private BufferedReader in_reader;
private PrintStream out_stream;
public ProcessInputStreamHandler(final InputStream in_stream, final PrintStream out_stream) {
this.in_reader = new BufferedReader(new InputStreamReader(in_stream));
this.out_stream = out_stream;
}
@Override public void run() {
String line;
try {
while ((line = in_reader.readLine()) != null) {
out_stream.println(line);
}
} catch (Exception e) {throw new Error(e);}
out_stream.flush();
}
}
现在来看我的问题陈述:虽然脚本的执行大约需要17秒,但是“封装的”执行至少需要21秒。 这4秒钟或更多秒会在哪里丢失?
我已经尝试过使用带有STDERR重定向到STDOUT的ProcessBuilder
,使用POSIX vfork和类似https://github.com/axiak/java_posix_spawn之类的库,使用字节缓冲区而不是BufferedReader
...一切都没有积极的结果。
有什么建议吗? 我了解会有一些性能损失,但是4秒对我来说似乎有点...
感谢任何建议!
最好的问候和在此先感谢。
完成任务的最快方法是使用Java 7和
return new ProcessBuilder(cmdarray).inheritIO().start().waitFor();
如果那没有帮助,我认为您无能为力,因为其他所有方法都会在您的运行时环境中添加更多必须处理的代码。
不知道它是否会提高性能,但是您可以尝试使用NuProcess库,该库在提供非阻塞(异步)I / O的同时也将在Linux上使用vfork,这确实减少了进程启动时间(和内存开销)。相当多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.