【问题标题】:Compiling and executing using exec in Java fails using command that works from the command line在 Java 中使用 exec 编译和执行失败,使用从命令行工作的命令
【发布时间】:2015-03-10 02:11:08
【问题描述】:

所以想法是下面代码中的这一行

Runtime.getRuntime().exec("cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA");

应该和这条线做同样的事情

cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA

当第二行从终端运行时。也就是编译运行java代码。我是否误解了 exec() 的工作原理?如果是这样,完成我想要完成的事情的最佳方式是什么?

package PackA;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;


public class classA {
    public static void main(String[] args) throws Exception{
        ClassLoader loader = classA.class.getClassLoader();

        //Sets the file path to the path of the current .java file
        File file = new File(loader.getResource(classA.class.getPackage().getName()+"/"+classA.class.getSimpleName()+".class").toString().replaceAll("file:", "").replaceAll("bin", "src").replaceAll("sA.class", "sA.java"));

        BufferedReader in = new BufferedReader(new FileReader(file)); //establishes the reader that will be used to read this .java file    
        StringBuffer string = new StringBuffer(); //the stringBuffer that will be used to hold the contents of this .java file
        String stringRead = in.readLine(); //sets a string to the first line of this .java file

        while((stringRead) != null){ //as long as we haven't reached the end of the file
            string.append(stringRead); //append the line
            string.append(System.getProperty("line.separator")); //go to the next line
            stringRead = in.readLine(); //read the next line
        }

        Integer intToFind = new Integer(0); //the integer being looked for

        if (intToFind<=10) { //as long as the intToFind is less than or equal to 10
            //increment the intToFind in the stringBuffer 
            StringBuffer newProgram = new StringBuffer(string.toString().replaceFirst("[(]"+intToFind.toString(), "("+String.valueOf(++intToFind)));
            //establishes the writer that will be used to write to the file
            BufferedWriter out = new BufferedWriter(new FileWriter(file));

            out.write(newProgram.toString()); //write the newProgram to this .java file with the incremented intToFind

            in.close(); //close both the reader and writer
            out.close();

            //Go to the directory of the java file, compile the code, move down one directory, execute the .class file
            Runtime.getRuntime().exec("cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA");
        }
    }
}

【问题讨论】:

    标签: java shell file-io exec


    【解决方案1】:

    cd 不是程序,它是一个 shell 命令。

    您可以改用ProcessBuilder,这将允许您定义应从中执行命令的工作目录上下文

    类似this for example

    上一个示例的缩写代码,已更新以提供指定工作目录的能力

    public int compile(String file, File workingDirectory) throws IOException, InterruptedException {        
        ProcessBuilder pb = new ProcessBuilder("javac", file);
        pb.redirectError();
        pb.directory(new File(workingDirectory));
        Process p = pb.start();
        InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
        consumer.start();
    
        int result = p.waitFor();
    
        consumer.join();
    
        System.out.println(consumer.getOutput());
    
        return result;        
    }
    
    public class InputStreamConsumer extends Thread {
    
        private InputStream is;
        private IOException exp;
        private StringBuilder output;
    
        public InputStreamConsumer(InputStream is) {
            this.is = is;
        }
    
        @Override
        public void run() {
            int in = -1;
            output = new StringBuilder(64);
            try {
                while ((in = is.read()) != -1) {
                    output.append((char) in);
                }
            } catch (IOException ex) {
                ex.printStackTrace();
                exp = ex;
            }
        }
    
        public StringBuilder getOutput() {
            return output;
        }
    
        public IOException getException() {
            return exp;
        }
    }
    

    您可以使用类似...的方式调用它

    compile("PackA/classA.java", new File("/Users/fnord/Documents/workspace/LearningJava/src"));
    

    现在,如果你真的很勇敢,可以看看How do you dynamically compile and load external java classes?,它使用 javax.tools.JavaCompiler` 类来编译 Java 文件...

    【讨论】:

      猜你喜欢
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多