2010-05-20 101 views
1

我試圖從Java代碼執行程序。這裏是我的代碼:從Java執行外部程序

public static void main(String argv[]) { 
    try { 
     String line; 
     Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable -o filename.txt"}); 
     BufferedReader input = new BufferedReader(
      new InputStreamReader(p.getInputStream())); 
     while ((line = input.readLine()) != null) { 
     System.out.println(line); 
     } 
     input.close(); 
    } catch (Exception err) { 
     err.printStackTrace(); 
    } 
} 

我的操作系統是Mac OS X 10.6。

現在,我試圖運行的可執行文件應該吐出輸出到filename.txt。如果我使用此命令並在終端上運行它,它會正常工作,並且filename.txt也會被填充。但是,從我的Java程序文件不創建。

如果我使用可執行文件> filename.txt,那麼filename.txt被創建,但是是空的。不知道這裏有什麼問題。我試圖運行的可執行文件是Xtide(如果有幫助的話)。

我真的很感謝任何幫助,我可以得到。

感謝,

+0

這是來自http://stackoverflow.com/questions/2874591/execute-external-program-from-java/2874687#2874687的後續內容。 – mdma 2010-05-20 15:43:01

回答

2

你不能重定向輸出到文件和讀取Java中的輸出。它是一個或另一個。你想要的是這樣的:

 Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable -o filename.txt"}); 
     p.waitFor(); 
     BufferedReader input = new BufferedReader(
      new InputStreamReader(new FileInputStream("filename.txt"))); 
     while ((line = input.readLine()) != null) { 
     System.out.println(line); 
     } 

的主要變化是:

  • p.waitFor(),因爲流程的執行是異步的,所以你必須等待它完成。
  • 將數據從文件而不是從過程的輸出讀取(因爲這將是空的。)
+0

這樣做的主要問題是filename.txt沒有被我的程序創建。如果我在終端上使用完全相同的命令,它會創建。你能想到任何原因爲什麼會發生?我已經設置了該文件夾的所有讀/寫權限。 – 2010-05-20 15:22:46

+0

我會在命令中創建文件名,並在創建FileInputStream絕對時創建文件名,以免遇到任何工作目錄問題。 – mdma 2010-05-20 15:24:48

+0

@Saurabh作爲一個猜測,過程因爲沒有添加p.waitFor()而提前終止。 – 2010-05-20 15:27:10

1

從搖頭丸工程(我投它)的答案,但你可能還需要考慮在哪裏你直接從executable讀取輸出數據流的版本:

Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable"}); 
p.waitFor(); 
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_; 
while ((line = input.readLine()) != null) { 
    System.out.println(line); 
} 
+0

這是我第一次嘗試。它沒有這樣工作,因此現在我試圖將輸出吐到一個文件然後讀取它。 – 2010-05-20 15:34:08

0

糾正我,如果我錯了,但症狀如下:

  • exec("/usr/bash", "-c", "executable > filename.txt")創建一個空文件。
  • exec("/usr/bash", "-c", "executable -o filename.txt")不創建文件。
  • 上面的一個或兩個都給出了一個退出代碼255當你看它。
  • 當您從命令行運行命令executable -o filename.txtexecutable > filename.txt它按預期工作。

在上面的光,我認爲最可能的原因是/bin/bash沒有找到executable當您從Java啓動它。第一個示例創建空文件的事實意味着/bin/bash正在做某件事。但是,如果你嘗試從一個bash shell中運行

$ unknown-command > somefile.txt 

提示,你會得到一個錯誤信息說,該命令無法找到和一個空的「something.txt」文件。 (您的Java應用程序中看不到錯誤消息,因爲它正在寫入stderr,而您沒有捕獲它。)創建空的「something.txt」文件的原因是它由shell 之前它試圖分叉並執行「可執行文件」。

如果這是問題,那麼簡單的解決方案是使用可執行文件的絕對路徑名。另外,如果您沒有執行任何命令行重定向或其他shell魔術,則不需要在新的bash實例中運行可執行文件。相反,只是這樣做:

Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt"); 

然後等待該過程完成,並試圖讀取該文件內容之前檢查退出代碼。

+0

這是對我答案中的評論的一個很好的解釋! :) – mdma 2010-05-21 10:24:33

+0

@mdma - 我覺得我做的比這更多...... – 2010-05-21 13:14:31