2012-07-27 32 views
17

Tôi có một quá trình java in ra rất nhiều văn bản. Đôi khi tôi chỉ muốn xem một chút văn bản. Với các chương trình bình thường tôi có thể làm:Làm thế nào để có được java để thoát ra khi đường ống đến đầu

$ myprog | head 

Tôi sẽ chỉ thấy 10 dòng đầu ra từ myprog và nó sẽ thoát ngay lập tức. Nhưng với java, nếu tôi làm:

$ java MyClass | head 

Tôi nhận được 10 dòng đầu tiên, nhưng quá trình java sẽ không thoát cho đến khi nó được thực hiện với tất cả quá trình xử lý. Nó giống như java không quan tâm rằng stdout (System.out) đã biến mất và quá trình head đã chết và biến mất.

Tất cả các chương trình khác hoặc là cảnh âm thầm, giống như mèo:

$ cat /etc/group | head 
root:x:0: 
daemon:x:1: 
bin:x:2: 
sys:x:3: 
adm:x:4: 
tty:x:5: 
disk:x:6: 
lp:x:7: 
mail:x:8: 
news:x:9: 

Hoặc thoát với một đường ống bị hỏng lỗi/ngoại lệ, như trăn:

$ python -c 'while True: print "hi"' | head 
hi 
hi 
hi 
hi 
hi 
hi 
hi 
hi 
hi 
hi 
Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
IOError: [Errno 32] Broken pipe 

Làm thế nào có thể nhận được java để nâng cao một ngoại lệ khi gọi System.out.println() khi tôi đầu ra đường ống cho một cái gì đó như đầu? Tôi rất muốn có thể làm một cái gì đó như:

try { 
    while(true) { 
     System.out.println("hi"); 
    } 
} catch(BrokenPipeException e) { 
    // exit gracefully 
} 
+1

SIGPIPE được gửi đến quá trình java trong trường hợp này, nhưng tôi không chắc chắn về những gì java làm với nó. Nếu bạn có thể kiểm tra xem JVM đã nhận được một sigpipe và chết, nó sẽ hoạt động. –

+0

Java thực hiện những điều đặc biệt với các tín hiệu và tôi biết từ các vấn đề khác mà nó không thể thiết lập một chương trình java để bẫy tín hiệu. – onlynone

Trả lời

1

Nếu bạn không thích các phương pháp .checkError() từ Sascha's answer và thà nhận trường hợp ngoại lệ, bạn có thể sử dụng

OutputStream stream = new FileOutputStream(FileDescriptor.out); 

Bạn mất PrintStream cụ thể chức năng. Trong trường hợp của tôi, chúng không liên quan và cách tiếp cận này dễ hơn là xây dựng một loạt các kiểm tra hacky.

Lưu ý rằng thao tác này sẽ không hoạt động nếu bạn đã chuyển hướng System.out qua System.setOut, dưới dạng FileDescriptor.out sẽ trỏ đến trình mô tả đầu ra ban đầu, chứ không phải chuyển hướng đầu ra của bạn.

11

Tôi đang sử dụng checkError()

Từ PrintStream-API-Docu:

Không giống như dòng đầu ra khác, một PrintStream không bao giờ ném một IOException; thay vào đó, các tình huống đặc biệt chỉ đơn thuần là đặt một cờ nội bộ có thể được kiểm tra thông qua phương thức checkError.

vì vậy hãy thử somthing như thế này:

 while(!System.out.checkError()) { 
      System.out.println("hi"); 
     } 
+0

Cảm ơn những người đứng đầu về tài liệu. Tôi đã tìm kiếm ở khắp mọi nơi cho một cái gì đó như thế, nhưng vì một lý do nào đó đã lướt qua mô tả cấp cao nhất. Đó là siêu gây phiền nhiễu, và nó có vẻ như nó sẽ không hiệu quả để gọi checkError mỗi lần thay vì chỉ là một thử-catch. – onlynone

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