6

我需要以用户可以与刚刚启动的程序交互的方式启动外部可执行文件。

例如,在 OpenSuse Linux 中有一个包管理器 - Zypper。您可以在命令模式下启动 zypper 并向其发出安装、更新、删除等命令。

我想以用户可以与之交互的方式从 Java 代码运行它:输入命令并查看他启动的程序的输出和错误。

这是我尝试使用的 Java 代码:

public static void main(String[] args) throws IOException, InterruptedException {
    Process proc = java.lang.Runtime.getRuntime().exec("zypper shell");

    InputStream stderr = proc.getInputStream();
    InputStreamReader isr = new InputStreamReader(stderr);
    BufferedReader br = new BufferedReader(isr);
    String line = null;
    char ch;

    while ( (ch = (char)br.read()) != -1)
        System.out.print(ch);

    int exitVal = proc.waitFor();
    System.out.println("Process exitValue: " + exitVal);
}

但不幸的是我只能看到它的输出:

zypper>

但无论我写什么,我的输入都不会影响启动的程序。我该怎么做?

4

3 回答 3

2

您需要获取输出流才能写入进程:

OutputStream out = proc.getOuptutStream();

此输出流通过管道传输到进程的标准输入流中,因此您只需写入它(也许您想PrintWriter先将其包装起来),数据将被发送到进程的标准输入。

proc.getErrorStream请注意,获取错误流 ( ) 以读取进程写入其 stderr 的任何错误输出也可能很方便。

API参考:

于 2010-11-20T11:41:03.287 回答
0

在您的示例中,while 条件内的转换似乎失败了,这似乎效果更好(我不运行 Suse,所以我没有尝试使用 Zypper):

public static void main(String[] args) throws IOException, InterruptedException
{
    //Process proc = java.lang.Runtime.getRuntime().exec("zypper shell");
    Process proc = java.lang.Runtime.getRuntime().exec("ping -t localhost");

    InputStream stderr = proc.getInputStream();
    InputStreamReader isr = new InputStreamReader(stderr);
    BufferedReader br = new BufferedReader(isr);

    int i;
    while ( (i = br.read()) != -1)
    {
        System.out.print((char) i);
    }

    int exitVal = proc.waitFor();
    System.out.println("Process exitValue: " + exitVal);
}
于 2010-11-20T11:49:07.513 回答
0

I recently wrapped Google Closure Compiler into a .jar-file which is extracted and used in a Process. This compiler only talks via System.in/out/err. There's a big "gotcha" in connecting pipes together, which is just briefly mentioned in the Process javadoc.

"...failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock."

On Mac OS X the buffer is 16k, and if you don't read it promptly as suggested, the process deadlocks. My only solution to this problem ATM, is a rather nasty busy wait.

https://github.com/algesten/googccwrap/blob/master/src/main/java/googccwrap/GoogleClosureCompilerWrapper.java

于 2010-11-20T21:56:39.453 回答