2009-03-14 29 views
6

Chương trình Java của tôi sử dụng ProcessBuilder (với redirectErrorStream được đặt đúng) và có một vòng lặp chạy phương thức đọc của luồng đầu vào của quy trình đang chặn. Chương trình bên ngoài mà tôi đang gọi sau đó dừng lại chờ đợi đầu vào và stdin. Bây giờ tôi muốn giết quá trình. Điều này không được thực hiện bởi (trong một thread riêng biệt) gọi phương thức tiêu hủy của quá trình, và gọi phương thức đóng của inputstream để ngăn chặn phương thức đọc khỏi chặn nữa, sao cho chuỗi ban đầu của tôi có thể kết thúc cuộc sống của nó?tại sao khối inputstream.close() của java?

Vì lý do nào đó, process.getInputStream().close() khối. Từ JavaDoc tôi không thấy lý do tại sao điều này có thể xảy ra. Hơn nữa, tôi không hiểu tại sao javadoc lại nói "Phương thức đóng của InputStream không làm gì cả." (link to javadoc) Ai đó có thể giải thích điều này?

Cảm ơn :-)

+0

Bạn có chắc chắn điều này không xảy ra do chương trình bên ngoài bạn đang chạy không? – Geo

Trả lời

4

Về hành vi chặn, có một vấn đề đã biết trong Java có thể gây ra bế tắc khi giao tiếp với một quy trình khác. Tôi không thể nói đây là những gì bạn đang nhìn thấy nhưng nó đáng xem xét. Các tài liệu cho java.lang.Process nói:

Bởi vì một số nền tảng bản địa chỉ cung cấp kích thước bộ đệm hạn chế cho đầu vào và đầu ra suối chuẩn, thất bại trong việc kịp thời viết input stream hoặc đọc các dòng sản phẩm của các tiến trình con có thể gây ra quy trình phụ để chặn và thậm chí là bế tắc.

+0

Tôi sẽ xem xét điều đó, cảm ơn – Allanrbo

+0

Tôi đã gặp sự cố tương tự. Có cách nào để đối phó với kích thước bộ đệm hạn chế và do đó tránh chặn các tiến trình con? – JorgeGRC

3

Đối với một số lý do process.getInputStream(). Close() khối. Từ JavaDoc, tôi không thấy lý do tại sao điều này có thể xảy ra. Hơn nữa, tôi không hiểu tại sao javadoc lại nói "Phương thức đóng của InputStream không không có gì". (liên kết đến javadoc) Có thể ai đó giải thích điều này?

Nếu bạn nhìn vào Javadoc, bạn sẽ thấy rằng InputStream là lớp trừu tượng. Các lớp con mở rộng InputStream được dự kiến ​​sẽ ghi đè lên phương thức close() (nếu cần). Rõ ràng lớp con InputStream mà bạn đang sử dụng thực hiện điều gì đó trong phương thức đóng.

+0

tất nhiên, có ý nghĩa tốt. Tôi đã không nhận thấy rằng inputstream là trừu tượng, cảm ơn. – Allanrbo

3

Thêm vào những gì jdigital đã viết, kiểm tra điều này article. Nó đề cập đến phương thức Runtime.exec()ProcessBuilder được giới thiệu trong Java 5, nhưng dường như với tôi, các cuộc thảo luận có thể được ngoại suy hóa cho các quy trình hệ thống nói chung.

3

Tôi nghĩ rằng tôi đã tìm ra điều này. Rõ ràng điều quan trọng là gọi process.getOutputStream(). Close() trước process.getInputStream(). Close() và process.getErrorStream(). Close().

+0

Tại sao việc đóng luồng đầu ra trước luồng đầu vào lại quan trọng? – Michael

+0

xin lỗi, tôi có nghĩa là "rõ ràng". Tôi không bao giờ tìm ra lý do tại sao ... – Allanrbo

+0

Cảm ơn :) Tôi sẽ hỏi một câu hỏi mới về SO về nó ... – Michael

-1

Tôi gặp vấn đề tương tự và sau khá nhiều khó khăn, đã tìm thấy giải pháp, bao gồm sử dụng InputStream#available() trước khi đọc bất kỳ nội dung nào từ luồng Process. Một đoạn giải pháp của tôi có sẵn here.

+0

Người bỏ phiếu có lẽ có thể giải thích quan điểm của mình. –

+0

Tôi đã không downvote bạn, nhưng tôi không nghĩ rằng điều này là chính xác. Việc gọi 'available()' cho bạn biết có bao nhiêu dữ liệu Java đã đọc, hoặc nhận thức được. Nó hoàn toàn có thể được viết cho bộ đệm của hệ điều hành và Java chưa có cơ hội để xem chúng. Một bài kiểm tra nhanh đã xác minh rằng 'available()' không nắm bắt được độ dài đầy đủ của một chuỗi 'echo'ed rất dài. – dimo414

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