2011-08-23 35 views
43

Tại sao một số luồng nhất định cần được xả (FileOutputStream và luồng từ Ổ cắm) trong khi luồng đầu ra tiêu chuẩn thì không?Khi nào/tại sao nên gọi System.out.flush() trong Java

Mỗi khi ai đó sử dụng các đối tượng System.outPrintStream, có thể là trong khi kêu gọi println() hay write(), họ không bao giờ tuôn dòng. Tuy nhiên, các lập trình viên khác thường gọi số flush() a PrintStream/PrintWriter với các luồng khác.

Gần đây tôi đã hỏi câu hỏi này cho một số lập trình viên và một số tin rằng có một số xử lý nền trong Java để tự động tuôn ra luồng System.out nhưng tôi không thể tìm thấy bất kỳ tài liệu nào về điều đó.

Điều gì đó khiến tôi tự hỏi liệu đơn giản là gọi System.out.println() là nền tảng độc lập vì một số hệ thống có thể cần bạn xóa luồng.

Trả lời

43

System.out dựa trên PrintStream theo mặc định sẽ xóa bất cứ khi nào dòng mới được viết.

Từ javadoc:

autoFlush - Một boolean; nếu đúng, bộ đệm đầu ra sẽ được rửa bất cứ khi nào một mảng byte được viết, một trong những println phương pháp được gọi, hoặc một ký tự xuống dòng hoặc byte ('\n') được viết

Vì vậy, các trường hợp println bạn đề cập đến được xử lý một cách rõ ràng và trường hợp write với số byte[] cũng được đảm bảo tuôn ra vì nó rơi vào "bất cứ khi nào mảng byte được ghi".

Nếu bạn thay thế System.out bằng cách sử dụng System.setOut và không sử dụng luồng tự động phát, thì bạn sẽ phải tuôn ra nó giống như bất kỳ luồng nào khác.

Mã thư viện có lẽ không nên sử dụng trực tiếp System.out, nhưng nếu có, thì nên cẩn thận để tuôn ra vì người dùng thư viện có thể ghi đè System.out để sử dụng luồng không xả.

Bất kỳ chương trình Java nào viết đầu ra nhị phân sang System.out phải cẩn thận trước flush trước exit vì đầu ra nhị phân thường không bao gồm một dòng mới.

+3

chỉ hợp lệ 'nếu đúng', nhưng phải không? Tôi không thể tìm thấy bất kỳ tài liệu nào về giá trị của autoFlush cho System.out ... –

+1

@Carlos, tùy thuộc vào hệ thống khởi động JVM và khởi chạy lớp chính 'System.out' và' System.err' là gì bị ràng buộc và cách chúng tuôn ra. Khi bạn sử dụng nhị phân 'java' để khởi động một lớp' System.out' được khởi tạo thành một cái gì đó như 'PrintStream mới (FileOutputStream mới (FileDescriptor.out), true, System.getProperty (" file.encoding "))' nhưng khác Các JVM khác nhau. Rõ ràng là một JVM nhúng applet làm một cái gì đó khác nhau. –

+0

@MikeSamuel, Vì vậy, nó có nghĩa là chúng tôi vẫn * cần * để tuôn ra anyway vì hành vi autoflush không ** đảm bảo ** bởi các thông số kỹ thuật? – Pacerier

2

System.out theo mặc định được xếp theo bộ đệm dòng. Vì vậy, nếu bạn đang gọi println và không phải là print thì đó không phải là vấn đề. Xem this article để biết thêm thông tin.

+1

Xin lỗi, println không cần phải được sử dụng để lấy autoflush cho PrintStream. Xin vui lòng xác minh. –

5

Từ PrintStream documentation:

tùy chọn, một PrintStream thể được tạo ra để tuôn tự động; điều này có nghĩa là phương thức flush được tự động gọi sau khi một mảng byte được viết, một trong các phương thức println được gọi, hoặc một ký tự dòng mới hoặc byte ('\n') được viết.

Mặc dù tôi không thấy nó được đề cập một cách rõ ràng trong tài liệu, đó là sự hiểu biết của tôi rằng System.out sẽ thực hiện tự động xả này.

3

Khi bạn không thể đợi mục được hiển thị, hãy xả luồng.

Khi JVM bị hỏng, không xả luồng có nguy cơ bị mất trong bộ đệm hiển thị, có thể làm cho thông báo lỗi hợp lý cho bạn biết tại sao JVM bị mất vĩnh viễn. Điều đó làm cho việc gỡ lỗi trở nên khó khăn hơn nhiều, khi mọi người sau đó có khuynh hướng nói, "nhưng nó đã không đến được đây, bởi vì nó sẽ in nó".

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