我有一个外部程序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
答案 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();
}
使用此代码。