use*_*444 91 java runtime.exec
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
Run Code Online (Sandbox Code Playgroud)
Joa*_*uer 138
有许多原因waitFor()无法归还.
但它通常归结为执行的命令不会退出的事实.
这也可能有很多原因.
一个常见原因是该过程产生一些输出,而您不从相应的流中读取.这意味着一旦缓冲区已满,该进程就会被阻止,并等待您的进程继续读取.你的进程反过来等待另一个进程完成(它不会因为它等待你的进程,...).这是一个经典的僵局.
您需要不断读取进程输入流以确保它不会阻塞.
有一篇很好的文章解释了所有的陷阱Runtime.exec()并展示了它们周围的方法,称为"当Runtime.exec()不会"(是的,文章来自2000,但内容仍然适用!)
Pet*_*rey 73
在等待输出完成之前,您似乎没有读取输出.仅当输出未填充缓冲区时才可以.如果是,它将等到你读取输出catch-22.
也许你有一些你不读的错误.这将使应用程序停止并等待永远等待.解决此问题的一种简单方法是将错误重定向到常规输出.
ProcessBuilder pb = new ProcessBuilder("tasklist");
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
System.out.println("tasklist: " + line);
process.waitFor();
Run Code Online (Sandbox Code Playgroud)
Rol*_*Boy 40
也来自Java doc:
java.lang中
课程流程
由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞甚至死锁.
无法从Process清除输入流的缓冲区(管道到子进程的输出流)可能导致子进程阻塞.
试试这个:
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();
Run Code Online (Sandbox Code Playgroud)
Slo*_*pes 10
我想在之前的答案中添加一些内容,但由于我没有代表发表评论,我只想添加一个答案.这是针对用Java编程的android用户.
根据RollingBoy的帖子,这段代码几乎对我有用:
Process process = Runtime.getRuntime().exec("tasklist");
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((reader.readLine()) != null) {}
process.waitFor();
Run Code Online (Sandbox Code Playgroud)
在我的情况下,waitFor()没有释放,因为我正在执行一个没有返回的语句("ip adddr flush eth0").解决这个问题的一个简单方法就是确保始终在语句中返回一些内容.对我来说,这意味着执行以下操作:"ip adddr flush eth0 && echo done".你可以整天读取缓冲区,但如果没有返回任何内容,你的线程将永远不会释放它的等待.
希望有人帮助!
有几种可能性:
stdout。stderr。stdin。正如其他人提到的,您必须使用stderr和stdout。
与其他答案相比,从Java 1.7开始,它甚至更加容易。您不必再自己创建线程来读取stderr和stdout。
只需将ProcessBuilder和redirectOutput结合使用方法和redirectError或即可redirectErrorStream。
String directory = "/working/dir";
File out = new File(...); // File to write stdout to
File err = new File(...); // File to write stderr to
ProcessBuilder builder = new ProcessBuilder();
builder.directory(new File(directory));
builder.command(command);
builder.redirectOutput(out); // Redirect stdout to file
if(out == err) {
builder.redirectErrorStream(true); // Combine stderr into stdout
} else {
builder.redirectError(err); // Redirect stderr to file
}
Process process = builder.start();
Run Code Online (Sandbox Code Playgroud)