Java runtime.exec是否立即将EOF发送到输入?
这是我通过java在Windows中启动进程(并获取输出)的代码 不知何故,正在讨论的程序(进程)正在立即接收EOF(如在“exec”行的“I”步骤之后),因此在调用runtime.exec后立即抛出错误(检测到,无效)消息。我可以通过命令提示符手动运行此程序,而不会出现此问题,但已确认在windows上发送ctrl-z是导致此消息的原因 有人知道这是什么原因吗Java runtime.exec是否立即将EOF发送到输入?,java,command-line,process,exec,Java,Command Line,Process,Exec,这是我通过java在Windows中启动进程(并获取输出)的代码 不知何故,正在讨论的程序(进程)正在立即接收EOF(如在“exec”行的“I”步骤之后),因此在调用runtime.exec后立即抛出错误(检测到,无效)消息。我可以通过命令提示符手动运行此程序,而不会出现此问题,但已确认在windows上发送ctrl-z是导致此消息的原因 有人知道这是什么原因吗 如果有必要的话,我已经尝试以“test.exe”而不是cmd/c test.exe直接运行该进程,但是当我这样做时,我无法通过inpu
如果有必要的话,我已经尝试以“test.exe”而不是cmd/c test.exe直接运行该进程,但是当我这样做时,我无法通过inputStream看到输出。当我在没有/c的情况下执行cmd test.exe时,没有区别。去掉“cmd”和“/c”。目前,您正在将输出馈送到cmd.exe,而不是test.exe。您的代码看起来应该可以工作(有一个警告,请参见下文) 我逐字记录了您的代码,并将
test.ext
替换为sort
,它可以从管道stdin读取
如果我按原样运行代码,它将启动sort命令,等待输入。它挂起在child.waitFor()
处,因为您没有关闭输出流以指示EOF。当我添加close()
调用时,一切正常
我建议您查看
test.exe
,确定它是否能够从管道stdin读取数据,或者是否需要控制台输入。问题是,当我按照您所说的做时,不知何故,我没有像我在文章末尾提到的那样,通过输入流从程序接收任何stdout。你知道为什么会这样吗?我之所以使用cmd/c,是因为除了这个特定的命令行工具外,它可以与其他任何命令行工具一起使用。@user1309154请参见Jim Garrison的答案。在调用waitFor()
之前,必须先关闭输出流。谢谢Jim,这正是我需要的。看起来程序不像sort或其他cmd行实用程序那样处理stdin。
public static void main(String[] args) throws Exception {
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/C";
command[2] = "test.exe";
final Process child = Runtime.getRuntime().exec(command);
new StreamGobbler(child.getInputStream(), "out").start();
new StreamGobbler(child.getErrorStream(), "err").start();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
child.getOutputStream()));
out.write("exit\r\n");
out.flush();
child.waitFor();
}
private static class StreamGobbler extends Thread {
private final InputStream inputStream;
private final String name;
public StreamGobbler(InputStream inputStream, String name) {
this.inputStream = inputStream;
this.name = name;
}
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
inputStream));
for (String s = in.readLine(); s != null; s = in.readLine()) {
System.out.println(name + ": " + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}