2008-09-13 67 views
28

Nếu tôi bắt đầu quá trình qua lớp ProcessBuilder của Java, tôi có toàn quyền truy cập vào các tiêu chuẩn của quy trình đó, tiêu chuẩn và các luồng lỗi chuẩn như Java InputStreamsOutputStreams. Tuy nhiên, tôi không thể tìm cách kết nối liền mạch các luồng đó với số System.in, System.outSystem.err.Bắt đầu quá trình với stdin/stdout/stderr kế thừa trong Java 6

Có thể sử dụng redirectErrorStream() để nhận đơn InputStream có lỗi tiêu chuẩn và lỗi chuẩn của quy trình con và chỉ lặp lại và gửi thông qua tiêu chuẩn của tôi — nhưng tôi không thể tìm cách để làm điều đó và để người dùng nhập vào quy trình, vì họ có thể nếu tôi sử dụng cuộc gọi C system().

Điều này dường như có thể xảy ra trong Java SE 7 khi xuất hiện — tôi chỉ tự hỏi liệu có giải pháp nào không. Điểm thưởng nếu kết quả của isatty() trong quá trình con thực hiện thông qua chuyển hướng.

+0

Rất tiếc, tôi không thể trợ giúp. – jjnguy

+0

Không sao cả. (Tôi không phải là một trong những người downvoted bạn, bằng cách này.) –

+0

Heh, tốt, nhờ anh chàng mà un-down-bình chọn cho tôi. Và cảm ơn, John đã không làm tôi thất vọng. – jjnguy

Trả lời

15

Bạn sẽ cần phải sao chép các luồng Process ra, lỗi và luồng nhập vào phiên bản Hệ thống. Cách dễ nhất để thực hiện điều đó là sử dụng lớp IOUtils từ gói IO của Commons. copy method có vẻ là những gì bạn cần. Các lời gọi phương thức sao chép sẽ cần phải nằm trong các luồng riêng biệt.

Đây là mã cơ bản:

// Assume you already have a processBuilder all configured and ready to go 
final Process process = processBuilder.start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getOutputStream(), System.out); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getErrorStream(), System.err); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(System.in, process.getInputStream()); 
} }).start(); 
+4

Không hoàn toàn. IOUtils.copy lấy InputStream làm đối số đầu tiên của nó, do đó sẽ không hoạt động với getOutputStream. Vì vậy, nó là IOUtils.copy (process.getInputStream(), System.out); Đó là một chút khó hiểu, như getOutputStream thực sự đường ống để đầu vào của quá trình. – Eelco

+0

Cấu trúc của điều này có vẻ đúng, nhưng tôi cũng đồng ý rằng các tham số đối với IOUtils có vẻ là từ khoá. process.getInputStream() là những gì nên được piped để stdout (yeah, nó âm thanh ngược). Vì vậy, trong khi cấu trúc của điều này có vẻ tốt, các cuộc gọi đến IOUtils nhìn sai và bây giờ có một chút bối rối ... – titania424

+1

Sai. Điều này chỉ ** ống ** dữ liệu giữa các luồng đầu vào/đầu ra của cha mẹ và con, không để cho nó ** kế thừa ** chúng. Ví dụ ngay cả khi lệnh Java được bắt đầu trên một thiết bị đầu cuối (C isatty() == true, hoặc System.console()! = Null), con sẽ không thấy chính nó đang được chạy trong một thiết bị đầu cuối, bởi vì các luồng đầu vào/đầu ra của nó là đường ống. Điều này là quan trọng bởi vì một số (hầu hết) các chương trình hoạt động khác nhau khi chúng được chạy trong một thiết bị đầu cuối. ProcessBuilder.Redirect.INHERIT của Java 7 hoạt động chính xác trong lĩnh vực này. – Tobia

13

Một biến thể của câu trả lời của John đó biên dịch và không yêu cầu bạn phải sử dụng Commons IO:

private static void pipeOutput(Process process) { 
    pipe(process.getErrorStream(), System.err); 
    pipe(process.getInputStream(), System.out); 
} 

private static void pipe(final InputStream src, final PrintStream dest) { 
    new Thread(new Runnable() { 
     public void run() { 
      try { 
       byte[] buffer = new byte[1024]; 
       for (int n = 0; n != -1; n = src.read(buffer)) { 
        dest.write(buffer, 0, n); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 
} 
+0

Không trả lời câu hỏi cho System.in. – solotim

+0

Tại sao đường ống (System.in, process.getOutputStream()); dường như không hoạt động? –

3

Đối System.in sử dụng sau đây pipein() thay vì pipe()

pipein(System.in, p.getOutputStream()); 

Triển khai:

private static void pipein(final InputStream src, final OutputStream dest) { 

    new Thread(new Runnable() { 
     public void run() { 
      try { 
       int ret = -1; 
       while ((ret = System.in.read()) != -1) { 
        dest.write(ret); 
        dest.flush(); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 

} 
+0

Điều này không thể hoạt động. –

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