2017-11-18 149 views
0

我遇到了一個令人討厭的小錯誤,我不知道如何解決它。我想要做的事很簡單:使用ProcessBuilder運行一個外部的.java文件。就像那個標題所暗示的那樣。使用ProcessBuilder在.java文件中運行shell命令

問題是,運行並創建此ProcessBuilder的文件與我想運行的其他文件不在同一個目錄中。

我試圖做來解決這個問題是:

String command[] = {"javac",JAVA_FILE_LOCATION}; 
ProcessBuilder processBuilder = new ProcessBuilder("cd"); 
Process process0 = processBuilder.start(); 

重置目錄和

processBuilder = new ProcessBuilder(command); 
Process process = processBuilder.start(); 

編譯其他文件

if(process.getErrorStream().read() != -1){ 
    print("Compilation Errors",process.getErrorStream()); 
} 

,只是一些錯誤處理在這裏。但它不會超過這個錯誤句柄部分。我無法弄清楚這樣做的正確方法。這裏的錯誤信息:

my_PC:Processes user$ java -jar process.jar 
************* Compilation Errors*********************** 
avac: file not found: /Users/Desktop/Piano.java 
Usage: javac <options> <source files> 
use -help for a list of possible options 
Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited 
at java.lang.UNIXProcess.exitValue(UNIXProcess.java:423) 
at my.package.address.Main.main(Main.java:28) 

有誰知道我在做什麼錯?如果需要,我也可以發佈整個代碼,但我認爲這不是真的有關。

更新:加入我的代碼

package some.random.package; 

import java.io.*; 

public class Main { 
/** 
* Provide absolute JAVA file path 
*/ 
private static final String JAVA_FILE_LOCATION = "/Users/Desktop/piano.java"; 

    public static void main(String args[]) throws IOException 
    { 
     String command[] = {"javac",JAVA_FILE_LOCATION}; 
     ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("/Users/Desktop/")); 
     Process process = processBuilder.start(); 
     if(process.getErrorStream().read() != -1){ 
      print("Compilation Errors",process.getErrorStream()); 
     } 
     /** 
     * check if compile is successful 
     * 0 => successful 
     */ 
     if(process.exitValue() == 0) 
     { 
      process = new ProcessBuilder(new String[]{"java","piano"}).directory(new File("/Users/Desktop/")).start(); 
      if(process.getErrorStream().read() != -1) 
       print("Errors ",process.getErrorStream()); 
      else 
       print("Output ",process.getInputStream()); 

      /** 
      * Check if RuntimeException or Errors encounter during execution then print errors on console 
      * Otherwise print Output 
      */ 
     } 
    } 
    private static void print(String status,InputStream input) throws IOException 
    { 
     BufferedReader in = new BufferedReader(new InputStreamReader(input)); 
     System.out.println("************* "+status+"***********************"); 
     String line = null; 
     while((line = in.readLine()) != null){ 
     System.out.println(line); 
     } 
    in.close(); 
    } 
} 

回答

1

cd命令與第一個ProcessBuilder執行隻影響子進程,它不會改變主執行程序的工作目錄。 當您運行第二個ProcessBuilder時,它將具有作爲主程序的工作目錄, 完全不受以前的ProcessBuilder執行的cd的影響。

要從不同的目錄下執行一個程序,使用的ProcessBuilderdirectory(...)方法:

String command[] = {"javac", JAVA_FILE_LOCATION}; 
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("path/to/dir")); 
Process process0 = processBuilder.start(); 

順便說一句,路徑「/Users/Desktop/piano.java」看起來很奇怪。 Mac上用戶桌面的路徑通常爲/Users/username/Desktop, ,因此代碼中的路徑意味着您的用戶名是「Desktop」, 這非常不尋常。

而且,爲了使其更容易與程序工作, 我建議把基本目錄(/Users/username/Desktop)在一個變量, 而不是在多個地方硬編碼。 這樣就可以更容易地進行更改,無需在多個地方進行編輯。

+0

我明白了,這解釋了很多。所以如果我想在編譯後運行該文件。它就像'process = new ProcessBuilder(new String [] {「java」,「Piano」})。directory(new File(「Users/Desktop /」))。start();' –

+0

@MarcoNeves – janos

+0

好吧,現在我只是「沒有這樣的文件或目錄」。這可能是一個愚蠢的問題,但文件名必須包含在路徑中嗎?我的路徑只是'/ Users/Desktop',文件「piano.java」就在那裏。沒有包裝說明或任何東西。 –