2012-09-21 27 views
9

Có cách nào dễ dàng để đọc đầu ra từ tiến trình con không bị chặn không? Tôi đang cố gắng để gọi một chương trình C từ Java, nhưng dường như nó stdout khối đệm khi kết nối với đường ống và dòng đệm chỉ khi kết nối với giao diện điều khiển. Tôi không thể sửa đổi chương trình C.Unduffered subprocess stdout trên windows

Có thể có cách đánh lừa chương trình nghĩ rằng nó được kết nối với bảng điều khiển? Điểm thưởng cho một giải pháp hoạt động trên linux là tốt.

+1

Bạn có thể mở một ssh trên cùng một máy và chạy theo cách đó. Tôi nghi ngờ không có gì đơn giản để làm điều này. –

+0

"dòng đệm" xảy ra ở cấp hệ điều hành. Trên Linux, ví dụ, bạn sẽ làm một "ioctl()" để thiết lập thiết bị đầu cuối của bạn thành "chế độ thô". Có lẽ bạn có thể Google cho "Java terminal I/O", "Java curses" hoặc các từ khóa tương tự? – paulsm4

+0

Tôi đã thực hiện tìm kiếm toàn diện trên Internet và trên SO. Điều này có vẻ là một vấn đề phổ biến, nhưng tôi đã không tìm thấy một giải pháp duy nhất cho Windows –

Trả lời

-1

OK -

1) "Line đệm đầu vào" là một thành ngữ chung cho các chương trình giao diện điều khiển chế độ, có niên đại từ Unix gốc và sê-ri-mode bến VTxx.

2) Bạn có thể đọc I/O "thô, không bị quấy rầy" (một lần nhấn phím, thay vì một dòng tại một thời điểm), nhưng chi tiết là hệ điều hành cụ thể. Bất kể bạn cần để thực hiện trên một hệ điều hành cụ thể, bạn gần như chắc chắn có thể làm từ Java.

3) Có vẻ như bạn muốn có thể chặn phím "mũi tên lên" hoặc phím "lật xuống", khi điều đó xảy ra, trên bàn phím Windows. Có lẽ để chơi trò chơi hoặc để tương tác với giao diện người dùng chế độ giao diện điều khiển.

4) Có một số tùy chọn. Một bạn có thể muốn xem xét là "robot" API, được sử dụng để thử nghiệm:

Nếu đó là không đủ, xin vui lòng cho biết thêm chi tiết về chính xác như thế nào bạn đang cố gắng để có được Java của bạn chương trình tương tác với chương trình C (và làm rõ nếu nền tảng thực sự là dấu nhắc của Windows và DOS).

+0

Tôi không cần đầu vào thô, dòng đệm sẽ đủ. Tôi đã thử 'Runtime.getRuntime(). Exec (lệnh);' hoặc 'ProcessBuilder (lệnh) .start();' để thực thi chương trình C, và sau đó là 'process.getInputStream()' nhưng nó đã cho tôi một khối luồng đệm. –

-1

Bạn có thể chuyển hướng đầu ra c vào một tập tin và sau đó đuôi tập tin từ một thread trong java sử dụng

org.apache.commons.io.input.Tailer 
+0

Thật không may, việc ghi vào một tập tin gần như chắc chắn sẽ được lưu vào bộ đệm. –

+0

Người dùng trong nhận xét dưới đây cho biết việc xếp hàng theo đường là tốt. Chúng tôi muốn chuyển hướng đầu ra trực tiếp từ tập tin thực thi và không phải từ java, có thể nó hoạt động. – user1569047

+0

Tôi chưa bao giờ nghe nói về bất cứ điều gì trong Windows làm đệm đường; thông thường, đầu ra là khối đệm hoặc không bị chặn. Ở bất kỳ tỷ lệ nào, nếu việc chuyển hướng đến một đường ống bị chặn, việc chuyển hướng đến một tệp hầu như chắc chắn cũng sẽ bị chặn theo vùng đệm. Đây không phải là một vấn đề Java, nó phải làm với hành vi của thư viện runtime C trong tiến trình con. –

0

Bạn đã thử sử BUF_1_ biến môi trường = 0?

+0

Theo như tôi có thể nói từ tìm kiếm của Google, đây là một cơ chế được đề xuất để ngăn chặn đệm trong thư viện glibc, nhưng các nhà phát triển đã từ chối nó. Bạn có một tài liệu tham khảo tốt hơn? (Tôi đã thử nó với Visual Studio và nó không có vẻ làm việc.) –

-1

Cách tốt nhất để làm điều đó là sử dụng để đọc Chủ đề đầu ra

Những gì tôi sẽ làm là: sử dụng một Callable (một Runnable cũng sẽ làm việc) mà tôi cung cấp cho các đầu vào từ quá trình (process.getInputStream ()) và đầu ra nơi tôi muốn lưu trữ đầu ra. Điều tương tự cũng nên được thực hiện cho StdErr. Kết quả đầu ra có thể được đọc bằng cách sử dụng bất cứ điều gì bạn thích.

public Object call() throws IOException { 
     int bytesRead; 
     byte[] b = new byte [ this.maxBlockSize ]; 

     try { 
      while ((bytesRead = this.input.read (b)) != -1) { 
       this.output.write (b, 0, bytesRead); 
      } 
     } finally { 
      if (this.output != null) { 
       this.output.close(); 
      } 
     } 
     return null; 
    } 
+0

Điều đó không giải quyết vấn đề OPS. Đầu ra đang được đệm trong tiến trình con, không phải trong tiến trình cha. –

+0

Nếu nó được thực hiện theo cách này, nó không quan trọng nếu nó bị chặn bởi vì nó được đọc trong một chủ đề riêng biệt. – azl

+2

Bạn đang thiếu điểm, đó là ông cần đầu ra từ quá trình con ngay lập tức, không phải tại một số thời gian trong tương lai không xác định khi bộ đệm stdout của con cuối cùng đã lấp đầy. Việc đọc không chặn có nghĩa là chương trình của anh ta có thể thực hiện một số công việc khác trong khi nó đang chờ quá trình con, nhưng nó không giúp nó có được kết quả nhanh hơn. (Đặc biệt, hãy xem xét trường hợp tiến trình con đang đợi đầu vào, nhưng tiến trình cha mẹ cần xem đầu ra trước khi nó biết đầu vào nào gửi đi; các tiến trình sẽ bế tắc.) –

1

Nó không phải là một giải pháp tuyệt vời, nhưng thư viện thời gian chạy có lẽ không đệm cổng nối tiếp vì vậy nếu bạn đang tuyệt vọng đủ bạn có thể sử dụng một giả lập null-modem như com0com hoặc phái sinh đó.

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