在Java中通过终端执行外部程序

时间:2012-01-05 23:18:14

标签: java linux ubuntu terminal

我有一个外部程序Otter,它将参数作为参数获取并创建一个输出文件,也指定为参数。 因此,例如,如果我的输入是“proof.in”,并且我希望将输出放在“proof.out”文件中,我在终端中运行以下命令:

otter <proof.in >proof.out

“proof.in”文件必须与otter可执行文件位于同一文件中。

问题是我需要Java中的这个功能,因此在我的Java代码中我执行以下操作:

java.lang.Runtime.getRuntime().exec("otter <proof.in >proof.out")

但在此行之后,整个UI被冻结,没有任何反应,也没有生成输出文件。

有人能告诉我哪里弄错了吗?

提前致谢, Tamash

4 个答案:

答案 0 :(得分:5)

这是正常的:您正在尝试启动通常由shell发出的命令。

此处,<proof.in>proof.out被视为otter可执行文件的文字参数,而不是shell重定向。但是看到这个工具的主页,它将无法工作:它期望重定向通常提供的stdin上的数据。

您需要通过shell启动此命令,最好使用进程构建器:

final ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "otter <proof.in >proof.out");
final Process p = pb.start();

等等。

当然,您还应确保程序从正确的目录运行 - 幸运的是,ProcessBuilder也允许您这样做。

答案 1 :(得分:0)

这是另一个问题的link,其中有一个非常详细的答案,说明如何使用线程以异步方式正确执行此操作。这是不阻止主线程并挂起GUI的唯一方法。

private class ProcessResultReader extends Thread
{
    final InputStream is;
    final String type;
    final StringBuilder sb;

    ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
    {
        this.is = is;
        this.type = type;
        this.sb = new StringBuilder();
    }

    public void run()
    {
        try
        {
            final InputStreamReader isr = new InputStreamReader(is);
            final BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
            {
                this.sb.append(line).append("\n");
            }
        }
        catch (final IOException ioe)
        {
            System.err.println(ioe.getMessage());
            throw new RuntimeException(ioe);
        }
    }

    @Override
    public String toString()
    {
        return this.sb.toString();
    }
}

然后你像上面那样使用上面的类

try
{
    final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
    final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
    final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
    stderr.start();
    stdout.start();
    final int exitValue = p.waitFor();
    if (exitValue == 0)
    {
        System.out.print(stdout.toString());
    }
    else
    {
        System.err.print(stderr.toString());
    }
}
catch (final IOException e)
{
    throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
    throw new RuntimeException(e);
}

答案 2 :(得分:0)

如果您只想运行程序,请务必记住: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();

答案 3 :(得分:-1)

您可以看到执行命令时发生的事情:

   try {
        Process p=Runtime.getRuntime().exec ("cmd /c dir");

        InputStream is = p.getInputStream();

        BufferedReader br = new BufferedReader (new InputStreamReader (is));

        String aux = br.readLine();

        while (aux!=null) {
            System.out.println (aux);

            aux = br.readLine();
        }
    } 
    catch (Exception e) {
        e.printStackTrace();
    } 

使用此代码。