2012-01-05 55 views
0

我有一個外部程序Otter,它獲取某個文件名作爲參數,並創建一個輸出文件,也被指定爲參數。 因此,舉例來說,如果我輸入的是「proof.in」我希望我的輸出被置於「proof.out」的文件,我在終端中運行以下命令:通過Java中的終端執行外部程序

otter <proof.in >proof.out 

的「證明。 in「文件必須與otter可執行文件位於同一個文件中。

的問題是,我需要從Java這個功能,所以在我的Java代碼中,我做到以下幾點:

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

但此行之後,整個UI被凍結,什麼都不會發生,並且不產生輸出文件。

任何人都可以告訴我我錯了嗎?

由於提前, Tamash

+0

請問您的程序來實現一些用戶輸入?如果是這樣,它將等待輸入.. – 2012-01-05 23:23:51

+0

[執行另一個Java程序從我們的Java程序]可能的重複(http://stackoverflow.com/questions/7770094/executing-another-java-program-from-our-our -java-program) – 2012-01-05 23:29:34

回答

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也可以讓你做到這一點。

+0

+1對於工具研究 – 2012-01-05 23:26:59

+0

神奇的先生!非常感謝你! – 2012-01-05 23:35:45

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

與此代碼。

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

如果你只是想運行的程序上面的類,就永遠記住這一點: Process p=Runtime.getRuntime().exec ("cmd /c dir"); p.waitFor();