gpt4 book ai didi

java - ProcessBuilder:在不阻塞主线程的情况下转发已启动进程的 stdout 和 stderr

转载 作者:太空宇宙 更新时间:2023-11-04 13:03:32 24 4
gpt4 key购买 nike

我正在使用 ProcessBuilder 在 Java 中构建一个流程,如下所示:

ProcessBuilder pb = new ProcessBuilder()
.command("somecommand", "arg1", "arg2")
.redirectErrorStream(true);
Process p = pb.start();

InputStream stdOut = p.getInputStream();

现在我的问题如下:我想捕获该进程的 stdout 和/或 stderr 正在发生的任何事情,并将其异步重定向到 System.out 。我希望该进程及其输出重定向在后台运行。到目前为止,我发现执行此操作的唯一方法是手动生成一个新线程,该线程将连续从 stdOut 读取,然后调用 System.out 的相应 write() 方法。

new Thread(new Runnable(){
public void run(){
byte[] buffer = new byte[8192];
int len = -1;
while((len = stdOut.read(buffer)) > 0){
System.out.write(buffer, 0, len);
}
}
}).start();

虽然这种方法确实有效,但感觉有点肮脏。最重要的是,它给了我一个多线程来正确管理和终止。有没有更好的方法来做到这一点?

最佳答案

使用ProcessBuilder.inheritIO,它将子进程标准I/O的源和目标设置为与当前Java进程的源和目标相同。

Process p = new ProcessBuilder().inheritIO().command("command1").start();

如果 Java 7 不是一个选项

public static void main(String[] args) throws Exception {
Process p = Runtime.getRuntime().exec("cmd /c dir");
inheritIO(p.getInputStream(), System.out);
inheritIO(p.getErrorStream(), System.err);

}

private static void inheritIO(final InputStream src, final PrintStream dest) {
new Thread(new Runnable() {
public void run() {
Scanner sc = new Scanner(src);
while (sc.hasNextLine()) {
dest.println(sc.nextLine());
}
}
}).start();
}

当子进程结束时,线程将自动死亡,因为src将EOF。

关于java - ProcessBuilder:在不阻塞主线程的情况下转发已启动进程的 stdout 和 stderr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34706410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com