【问题标题】:Execute external program through terminal in Java在Java中通过终端执行外部程序
【发布时间】:2012-02-03 19:10:27
【问题描述】:

我有一个外部程序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 被冻结,没有任何反应,也没有生成输出文件。

谁能告诉我我哪里弄错了??

提前致谢, 塔玛什

【问题讨论】:

标签: java linux ubuntu terminal


【解决方案1】:

如果您只想运行该程序,请始终记住这一点: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();

【讨论】:

    【解决方案2】:

    这是另一个问题的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);
    }
    

    【讨论】:

      【解决方案3】:

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

      这里,&lt;proof.in&gt;proof.out 被视为 otter 可执行文件的文字参数,而不是 shell 重定向。但是看到这个工具的主页,它不会工作:它需要重定向通常提供的标准输入上的数据。

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

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

      等等等等

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

      【讨论】:

      • 太棒了,先生!非常感谢!
      【解决方案4】:

      您可以在执行命令时看到发生了什么:

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

      使用此代码。

      【讨论】:

        猜你喜欢
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-09
        • 2012-04-03
        • 1970-01-01
        • 2012-02-15
        • 2018-08-21
        相关资源
        最近更新 更多