在Java中通过terminal执行外部程序

我有一个外部程序Otter获取作为参数一些文件名,并创build一个输出文件,也被指定为参数。 所以,例如,如果我的input是“proof.in”,我想我的输出放在“proof.out”文件中,我在terminal中运行以下命令:

otter <proof.in >proof.out 

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

问题是我需要从Java的这个function,所以在我的Java代码中,我做了以下工作:

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

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

任何人都可以告诉我,我错了吗?

在此先感谢,Tamash

Solutions Collecting From Web of "在Java中通过terminal执行外部程序"

这是正常的:你正试图启动一个通常由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也允许您这样做。

这里是一个链接到另一个问题与非常详细的答案如何以异步的方式与线程正确地做到这一点。 这是不阻止你的主线程和挂起你的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); } 

如果你只想运行这个程序,一定要记住: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor(); Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();

你可以看到当你执行命令时发生了什么:

  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(); } 

用这个代码。