使用ProcessBuilder在.java文件中运行shell命令

问题描述:

我遇到了一个令人讨厌的小错误,我不知道如何解决它。我想要做的事很简单:使用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(); 
    } 
} 

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”就在那里。没有包装说明或任何东西。 –