Java 使用process Builder重定向流程的输出
我正在尝试在自己的控制台窗口中运行plink。我从使用Process.exec()开始,效果很好。我改为使用ProcessBuilder,现在输出在我终止进程之前不会发送 我的代码如下所示:Java 使用process Builder重定向流程的输出,java,Java,我正在尝试在自己的控制台窗口中运行plink。我从使用Process.exec()开始,效果很好。我改为使用ProcessBuilder,现在输出在我终止进程之前不会发送 我的代码如下所示: class ConsoleOutputThread extends Thread { public void start(String processName) { // this was old code: Runtime r = Runtime.getRuntime()
class ConsoleOutputThread extends Thread {
public void start(String processName) {
// this was old code: Runtime r = Runtime.getRuntime();
try {
builder = new ProcessBuilder("plink", "-ssh", "192.168.3.21");
builder.redirectErrorStream(true);
process = builder.start();
//this was old code: process = r.exec (processName);
} catch (IOException ex) {
}
start();
}
@Override
public void run() {
try {
BufferedReader is = new BufferedReader(new InputStreamReader(process.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
try {
process.waitFor();
} catch (InterruptedException ex) {
}
char b[];
b = new char[1];
while(is.read(b, 0, 1)> 0) {
// this is for debug, normally sent to console
System.out.println("Got character: " + b[0]);
}
} catch (IOException ex) {
}
}
}
因此,当使用Runtime.exec()时,一切都很好。现在,有了ProcessBuilder,读取函数将永远阻塞(实际上,直到我终止该进程,当everuthing被抛出时)。然而,错误流是有效的,也就是说,如果我放置了一个错误的选项,我会在控制台中获得消息。
我可能错过了一些东西,正在寻求帮助。
谢谢您已经将
plink
进程设置为将其输出写入连接到java进程的管道。通过plink
进程输出的任何内容都将保存在操作系统缓冲区中,直到您的进程读取为止。操作系统缓冲区的容量有限,如果plink
写入太多数据,那么它将阻塞,直到您的进程从缓冲区读取一些数据
不幸的是,java进程等待plink
进程完成,然后才从管道中读取任何内容。因此,如果plink
进程写入太多输出,它将无限期地阻塞
在调用
waitfor()
之前,应该更改java逻辑以读取plink
进程的输出 您是否flush()
您的流?waitFor()的可能重复导致了问题,程序挂起在那里。如果没有它,它就可以工作,但plink不会发送太多输出,而是等待另一个进程完成(ssh)。它要求输入密码,在连接并验证之前,它将一直处于waitFor()状态。因此,如果我注释掉waitFor(),它将继续。但是,ssh的输出(“root@192.168.3.21的密码:“)不会进入我的输入流,而是进入我启动jar文件的控制台(在Linux中,在Windows中,我认为plink的实现是不同的)。所以问题变成了“如何重定向调用另一个进程的进程的输出?”