2012-02-05 31 views
10

Trong Java, tôi nhận thấy rằng đôi khi, các câu lệnh System.err được in trước tiên trước câu lệnh System.out, mặc dù câu lệnh sau xuất hiện trước mã trước trong mã của tôi. Tại sao? Tôi tò mò.Tại sao các câu lệnh System.err được in lần đầu tiên?

+0

Từ 1.02 Tôi đã mắc kẹt với việc sử dụng 'System.err' khi tôi truy cập chính xác vì lý do này. Không có ý tưởng làm thế nào nhiều phiên bản mới hơn của Java hành xử, bởi vì tôi không kiểm tra nó ra. –

Trả lời

17

Thông thường, System.out là luồng đầu ra được lưu vào bộ đệm, vì vậy văn bản được tích lũy trước khi nó được chuyển sang vị trí đích. Điều này có thể cải thiện đáng kể hiệu suất trong các ứng dụng in số lượng lớn văn bản, vì nó giảm thiểu số lượng các cuộc gọi hệ thống đắt tiền phải được thực hiện. Tuy nhiên, điều đó có nghĩa là văn bản không phải lúc nào cũng được hiển thị ngay lập tức và có thể được in ra muộn hơn nhiều so với văn bản.

System.err, mặt khác, thường không được đệm vì thông báo lỗi cần được in ngay lập tức. Điều này là chậm hơn, nhưng trực giác là thông báo lỗi có thể là thời gian quan trọng và do đó chương trình làm chậm có thể được biện minh. Theo số the Javadoc for System.err:

Thông thường luồng này tương ứng với đầu ra hiển thị hoặc đích đầu ra khác được chỉ định bởi môi trường máy chủ hoặc người dùng. Theo quy ước, luồng đầu ra này được sử dụng để hiển thị thông báo lỗi hoặc thông tin khác cần chú ý ngay lập tức của người dùng ngay cả khi luồng đầu ra chính, giá trị của biến đó, đã được chuyển hướng đến một tệp hoặc đích khác thường không được theo dõi liên tục.

(nhấn mạnh của tôi)

Tuy nhiên, kết quả là, dữ liệu cũ gửi đến System.out có thể xuất hiện sau khi System.err thông điệp mới hơn, vì dữ liệu đệm cũ là đỏ ửng chậm nhất là thông điệp đã được gửi đến System.err. Ví dụ chuỗi sự kiện:

  • "Xin chào," được đệm để System.out
  • "hoảng loạn" được gửi trực tiếp đến System.err và được in ngay lập tức.
  • "thế giới!" được đệm để System.out, và các dữ liệu đệm được in

sẽ dẫn đến sản lượng

PANIC 
Hello, world! 

Mặc dù Hello được in để System.out trước PANIC được in để System.err.

Hy vọng điều này sẽ hữu ích!

+0

Chỉ cần ra khỏi sự tò mò: Liệu java có đảm bảo giống như Cdt stdout khi đường ống đến một thiết bị đầu cuối? I E. chúng ta tuôn ra bộ đệm mỗi khi một dòng mới được viết? – Voo

+0

@ Voo- Tôi chỉ nhìn vào Javadoc và có vẻ như không có gì thuộc loại này. – templatetypedef

+0

'PrintStream' được thực hiện để tuôn ra sau khi chỉ là về tất cả mọi thứ (tôi nghĩ rằng bạn có thể trực tiếp' viết' và nó không). –

2

Nó phải làm với đệm và ưu tiên. Có lẽ, Java (như C và dẫn xuất C) không đệm System.err, stderr, v.v., không giống như System.out, stdout, v.v. Theo cách này, hệ thống có thể đảm bảo rằng bạn sẽ nhận được mọi thông báo lỗi liên quan, ngay cả khi nó phải giảm đầu ra tiêu chuẩn vì một lý do nào đó hoặc lý do khác.

Từ Wikipedia:

Có thể chấp nhận và bình thường cho đầu ra tiêu chuẩn và sai số chuẩn để được dẫn đến cùng một điểm đến, chẳng hạn như các thiết bị đầu cuối văn bản.Thư xuất hiện theo cùng thứ tự như chương trình ghi chúng, trừ khi có liên quan đến bộ đệm. (Ví dụ, một tình huống phổ biến là khi luồng lỗi tiêu chuẩn không bị chặn nhưng luồng đầu ra tiêu chuẩn là dòng đệm, trong trường hợp này, văn bản được ghi vào lỗi chuẩn sau này có thể xuất hiện trên đầu cuối, nếu bộ đệm của luồng đầu ra tiêu chuẩn không chưa đầy đủ.)

+0

Tôi chưa bao giờ yêu thích bất kỳ ưu tiên nào cho các luồng .. cách hoạt động như thế nào? Tôi sẽ đi với lời giải thích đệm đơn giản. – Voo

+0

Chỉ là một vấn đề về ngôn ngữ hoa. Cố định kỹ thuật hơn :) –

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