2013-03-05 45 views
7

Tôi đang làm việc trên một chương trình java đơn giản. Nó đơn giản biên dịch và thực hiện một chương trình java khác. Tôi đang sử dụng hàm Runtime.exec() để biên dịch và chạy. Không có vấn đề gì với việc biên dịch. nhưng khi nó chạy, nếu chương trình thứ hai cần một đầu vào để đọc từ bàn phím, tôi không thể cho nó từ quá trình tổng thể. Tôi đã sử dụng hàm getOutputStream(). nhưng nó không thể giúp được. Tôi sẽ cung cấp mã của tôi.Chạy chương trình java từ một chương trình java khác

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(); 
     } 
    } 
} 

Đây là chương trình chính của tôi (sam.java).

Sau đây là mã của 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)); 

    } 
} 

Không có vấn đề, nếu chương trình thứ hai của tôi chỉ có báo cáo in ấn. Nhưng vấn đề nảy sinh khi tôi phải đọc cái gì đó từ cái kia.

+0

bạn sẽ phải thực hiện một số loại ống từ STDIN của sam đến sam2 nhưng điều đó có thể gây rắc rối nhiều hơn giá trị của nó. –

+0

Hãy tìm hiểu các quy ước đặt tên java và gắn bó với chúng, ở đây: tên lớp sẽ bắt đầu bằng một chữ hoa. – kleopatra

+0

tôi đã cố gắng trình bày một ví dụ đơn giản. cảm ơn cho lời khuyên của bạn .. :) – BBHeeMAA

Trả lời

18

Có một chút lạ nhưng bạn có thể chạy chương trình thứ hai mà không cần sử dụng nó. Chỉ cần gọi phương thức chính trong đó. Vì vậy, quên phần thời gian chạy và thực hiện điều này:

sam2.main(new String[0]); 

Tất nhiên cách này, bạn phải biên dịch sam2 tại thời gian biên dịch

+0

tôi couldnt hiểu những gì u có nghĩa là bởi tuyên bố này .. !! :( – BBHeeMAA

+1

Nó hoạt động .. :) cảm ơn rất nhiều .. Nhưng khi tôi sử dụng cách này .. toàn bộ kiểm soát sẽ được chuyển sang chương trình thứ hai. do đó, tổng thể sẽ thực hiện chỉ sau khi hoàn thành chương trình thứ hai .. nên tôi sử dụng chủ đề để giải quyết vấn đề này .. ?? – BBHeeMAA

+0

Tất nhiên là bạn nên làm. –

1

Bạn chỉ có thể gọi phương thức chính của lớp thứ hai. Phương thức chính giống như bất kỳ phương thức tĩnh nào khác.

9

Mỗi quá trình cần được phép chạy và hoàn tất. Bạn có thể sử dụng Process#waitFor cho mục đích này. Tương tự, bạn cần tiêu thụ bất kỳ đầu ra nào từ quá trình cùng một lúc. waitFor sẽ chặn, vì vậy bạn sẽ cần sử dụng số Thread để đọc đầu vào (và nếu bạn cần, hãy viết đầu ra cho quy trình)

Tùy thuộc vào vị trí của tệp java/class, bạn cũng có thể cần chỉ định bắt đầu thư mục mà từ đó việc thực hiện quá trình có thể bắt đầu.

Hầu hết những điều này dễ dàng hơn đáng kể sử dụng 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; 
     } 
    } 
} 

Bây giờ rõ ràng, bạn nên kiểm tra kết quả trở lại của các quá trình, và có thể tạo ra một cơ chế tốt hơn để tương tác với các quá trình, nhưng đó là ý tưởng cơ bản. ..

Các vấn đề liên quan