2012-04-18 68 views
5

Tôi muốn viết chương trình Java chạy lệnh "java myprog < input.txt> output.txt" bên ngoài. Mục tiêu cuối cùng là chạy lệnh này trên hai chương trình khác nhau và so sánh tương tự đầu ra của chúng với các tệp đầu ra tương ứng của chúng. Tôi nghĩ rằng tôi đã đọc tất cả các bài viết liên quan về việc sử dụng ProcessBuilder để chạy một chương trình bên ngoài và vài mục về xử lý đầu vào của người dùng trong chương trình bên ngoài đó, nhưng tôi vẫn không thể làm việc. Từ những gì tôi đã đọc, tôi nghĩ cách tiếp cận tốt nhất là không chạy lệnh chính xác ở trên, mà thay vào đó đọc tệp input.txt và nạp byte theo byte vào đối tượng Process, sau đó thu kết quả đầu ra và ghi nó vào đầu ra .txt ... Tôi đang mở 100% cho các tùy chọn khác.Chương trình Java chạy "java myprog < input.txt > output.txt"

Tôi kết hợp mã bên dưới dựa trên các bài đọc của mình. Có vẻ như cách nạp dữ liệu đầu vào chính xác từ input.txt vào myprog, nhưng khi tôi cố gắng in đầu ra của chương trình bên ngoài vào bàn điều khiển để xác minh, chương trình bị treo tại điểm mà đầu vào người dùng (ngạc nhiên) được mong đợi trong myprog.

Tôi nhận được cùng một vấn đề có và không có đường chuyển hướngErrorStream (true).

Tôi thực sự muốn điều này trong Java vì tôi dự định chia sẻ mã nguồn với những người có kết quả đầu ra chương trình tôi sẽ so sánh, và chúng chủ yếu chỉ quen thuộc với Java.

import java.io.*; 
import java.util.*; 

public class test7 { 

    public static void main(String args[]) { 

     try { 
      // WANT: "java myprog <input.txt> output.txt" 
      String inputFile = "input.txt"; 
      String outputFile = "output.txt"; 

      ProcessBuilder pb = new ProcessBuilder("java","myprog"); 
      pb.redirectErrorStream(true); // merge stdout, stderr of process 
      Process p = pb.start(); 

      // write input to the running program 
      OutputStream pos = p.getOutputStream(); 
      InputStream fis = new FileInputStream(inputFile); 
      int read = 0; 
      while ((read = fis.read()) != -1) { 
       pos.write(read); 
      } 
      fis.close(); 

      // get output of running program 
      InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
      BufferedReader br = new BufferedReader(isr); 

      // HANGS HERE WHEN USER INPUT REQUIRED 
      String lineRead; 
      while ((lineRead = br.readLine()) != null) { 
       System.out.println(lineRead); 
      } 

     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } // end main 

} 

Dưới đây là nội dung của myprog.java:

import java.io.*; 

public class myprog { 

    public static void main(String args[]) throws IOException { 

     System.out.println("Hello world!"); 
     System.out.println("Enter something:"); 

     BufferedReader cin = new BufferedReader(new InputStreamReader(System.in)); 

     // the readLine() command causes ProcessBuilder to hang 
     cin.readLine(); 
    } 
} 

Và file INPUT.TXT chỉ là

p 

Các tập tin output.txt nên

Hello world! 
Enter something: 
+0

Bạn có ý nghĩa gì khi người dùng nhập yêu cầu? Bạn có thể hiển thị myprog của bạn hoặc ít nhất là phần thích hợp nhất của nó? Ngoài ra, hãy làm theo các quy ước đặt tên Java nếu bạn muốn được trợ giúp tốt hơn tại đây. Việc bạn sử dụng cách đặt tên không chuẩn (bao gồm cả viết hoa chữ cái đầu tiên của tên lớp) sẽ làm cho mã của bạn khó hiểu. –

+2

Tôi đã trả lời câu hỏi này một thời gian trước .. http://stackoverflow.com/questions/3062305/executing-shell-commands-from-java/3062874#3062874 – dsmith

+0

@HovercraftFullOfEels: Tôi đã thêm nội dung của myprog.java vào mô tả. Tôi xin lỗi vì không viết hoa tên lớp. – missthang

Trả lời

0

Bạn đã từng nghĩ đến việc sử dụng Runtime.getRuntime() .exec() thay thế?

Process proc = Runtime.getRuntime().exec("java myprog "+inputFile+" "+outputFile); 
+0

Điều này không có lợi thế khi sử dụng ProcessBuilder. –

+0

Vẫn bị treo theo cùng một cách. – missthang

+0

Tôi đã để lại "<" and ">" trong ví dụ của tôi, bạn có thêm những thứ này không? @ Hovercraft ... 1 dòng mã vs 10 luôn luôn là một lợi thế trong cuốn sách của tôi, nhưng với mỗi của riêng họ. – user282172

0

Bạn có thể bao gồm bình 'myprog' và tự gọi chính phương thức main(). Thậm chí nhiều hơn như vậy nếu myprog là trong tên miền của bạn, bạn có thể thoát khỏi phương pháp chính hoàn toàn.

4

Tôi tự hỏi nếu vấn đề của bạn là một phần để làm với không sử dụng các chủ đề riêng biệt để đọc đầu vào và đầu ra bằng văn bản. Ví dụ:

public static void main(String args[]) { 

     try { 
     // WANT: "java myprog <input.txt> output.txt" 
     String inputFile = "input.txt"; 
     String outputFile = "output.txt"; 

     // my ProcessBuilder Strings will be different from yours 
     ProcessBuilder pb = new ProcessBuilder("java", "-cp", ".;bin;", 
       "yr12.m04.a.MyProg"); 
     pb.redirectErrorStream(true); 
     Process p = pb.start(); 

     final OutputStream pos = p.getOutputStream(); 
     final PrintWriter pw = new PrintWriter(pos); 
     final InputStream fis = new FileInputStream(inputFile); 
     final BufferedReader fileBr = new BufferedReader(new InputStreamReader(fis)); 

     InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
     final BufferedReader br = new BufferedReader(isr); 

     new Thread(new Runnable() { 
      public void run() { 
       String lineRead; 
       try { 
        while ((lineRead = br.readLine()) != null) { 
        System.out.println(lineRead); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } finally { 
        if (br != null) { 
        try { 
         br.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        } 
       } 
      } 
     }).start(); 

     new Thread(new Runnable() { 
      public void run() { 
       try { 
        String lineRead; 
        while ((lineRead = fileBr.readLine()) != null) { 
        pw.println(lineRead); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } finally { 
        if (pw != null) { 
        pw.close(); 
        } 
        if (fileBr != null) { 
        try { 
         fileBr.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        } 
       } 
      } 
     }).start(); 

     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } // end main 
+0

Vậy đó! Hoạt động hoàn hảo với chuyển đổi classpath từ lệnh java. Cảm ơn bạn rất nhiều!!!!! – missthang

+0

@missthang: vui vì bạn đã làm việc đó. –

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