16

私は単純なJavaプログラムに取り組んでいます。別のJavaプログラムをコンパイルして実行するだけです。Runtime.exec()関数を使用してコンパイルして実行しています。コンパイルに問題はありません。しかし、実行時に、2番目のプログラムがキーボードから読み取るために入力を必要とする場合、マスタープロセスからそれを与えることはできません。getOutputStream()関数を使用しました。しかし、それは仕方がありませんでした。コードを提供します。

public class sam {  
    public static void main(String[] args) throws Exception {  
        try { 
             Process p = Runtime.getRuntime().exec("javac sam2.java");
             Process p2 = Runtime.getRuntime().exec("java sam2");
             BufferedReader in = new BufferedReader(  
                                new InputStreamReader(p2.getInputStream()));

             OutputStream out = p.getOutputStream();
             String line = null; 
             line = in.readLine();
             System.out.println(line);
             input=input+"\n";
             out.write(input.getBytes());
             p.wait(10000);
             out.flush();
        }catch (IOException e) {  
             e.printStackTrace();  
        }  
    }  
}  

これは私のマスタープログラム(sam.java)です。

以下はsam2.javaのコードです

public class sam2 {  
public static void main(String[] args) throws Exception {  

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str; 
    System.out.println("Enter the number..\n");
    str = br.readLine(); 
    System.out.println(Integer.parseInt(str));

    }  
}  

2番目のプログラムに印刷ステートメントしかない場合は問題ありません。しかし、私が他から何かを読まなければならないときに問題が発生します。

4

5 に答える 5

21

少し奇妙ですが、2 番目のプログラムをフォークせずに実行できます。その中でメインメソッドを呼び出すだけです。したがって、runtime セクションは忘れて、次のようにします。

sam2.main(new String[0]);

もちろん、この方法では、コンパイル時に sam2 をコンパイルする必要があります

于 2013-03-05T08:30:09.953 に答える
14

各プロセスの実行と終了を許可する必要があります。Process#waitForこの目的で使用できます。同様に、プロセスからの出力を同時に消費する必要があります。 waitForブロックするため、 a を使用しThreadて入力を読み取る必要があります(必要な場合は、出力をプロセスに書き込みます)

java/class ファイルの場所によっては、プロセスの実行を開始できる開始フォルダーを指定する必要がある場合もあります。

これのほとんどは、使用するのが非常に簡単ですProcessBuilder

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class CompileAndRun {

    public static void main(String[] args) {
        new CompileAndRun();
    }

    public CompileAndRun() {
        try {
            int result = compile("compileandrun/HelloWorld.java");
            System.out.println("javac returned " + result);
            result = run("compileandrun.HelloWorld");
        } catch (IOException | InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public int run(String clazz) throws IOException, InterruptedException {        
        ProcessBuilder pb = new ProcessBuilder("java", clazz);
        pb.redirectError();
        pb.directory(new File("src"));
        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 int compile(String file) throws IOException, InterruptedException {        
        ProcessBuilder pb = new ProcessBuilder("javac", file);
        pb.redirectError();
        pb.directory(new File("src"));
        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;
        }
    }
}

明らかに、プロセスの戻り結果を確認する必要があり、プロセスとやり取りするためのより良いメカニズムを作成する必要がありますが、それが基本的な考え方です...

于 2013-03-05T09:40:21.717 に答える
1

2番目のクラスのmainメソッドを呼び出すだけです。mainメソッドは、他の静的メソッドとまったく同じです。

于 2013-03-05T08:32:02.733 に答える