2012-02-05 39 views
10

在Java中,我注意到有時,System.err語句在System.out語句之前首先打印,儘管後者在我的代碼中先於前者出現。爲什麼?我很好奇。爲什麼有時會首先打印System.err語句?

+0

從1.02我一直堅持使用'System.err'當我正在黑客正是這個原因。不知道Java的更新版本的行爲,因爲我沒有測試它。 – 2012-02-05 03:35:39

回答

17

通常,System.out是一個緩衝輸出流,因此文本在刷新到目標位置之前累積。這可以顯着提高打印大量文本的應用程序的性能,因爲它最大限度地減少了必須進行的昂貴系統調用的次數。但是,這意味着文本並不總是立即顯示,並且可能比寫入文本晚得多。

System.err另一方面,通常不會被緩衝,因爲需要立即打印錯誤消息。這是慢的,但直覺是錯誤信息可能是時間關鍵的,所以程序放緩可能是合理的。根據the Javadoc for System.err

典型地,這流對應於顯示輸出或由主機環境或用戶指定的另一個輸出目的地。 按照慣例,即使主輸出流(即變量out的值)已被重定向到文件或其他目的地,該輸出流也可用於顯示錯誤消息或其他應立即引起用戶注意的信息通常不會持續監控。

(我的重點)

然而,作爲一個結果,發送到System.out舊數據可能較新System.err消息後顯示出來,因爲舊的緩存的數據後刷新比消息發送到System.err。例如該序列的事件:

  • 「你好,」緩衝至System.out
  • 「PANIC」被直接發送到System.err並立即打印。
  • 「世界!」緩衝至System.out,並且將緩衝的數據被打印

將導致輸出

PANIC 
Hello, world! 

即使Hello印刷到System.outPANIC之前被印到System.err

希望這會有所幫助!

+0

只是出於好奇:Java在與終端連接時是否與C使用stdout相同的保證?即每次寫入換行符時我們都會刷新緩衝區? – Voo 2012-02-05 01:56:42

+0

@ Voo-我只是看着Javadoc,並沒有出現這種類型的東西。 – templatetypedef 2012-02-05 01:57:57

+0

'PrintStream'被實現在幾乎所有東西之後刷新(我認爲你可以直接'寫入'而不是)。 – 2012-02-05 03:34:12

2

它與緩衝和優先級有關。據推測,爪哇(如C和C衍生物)不緩衝System.errstderr等,不像System.outstdout,等等。這樣,系統可以確保你最有可能得到任何相關的錯誤消息,即使它出於某種原因必須降低標準輸出。

Wikipedia

這是可接受的和正常標準輸出和標準錯誤將被引導到相同的目的地,諸如文本終端。消息以與程序寫入相同的順序出現,除非涉及緩衝。 (例如,常見情況是標準錯誤流未緩衝,但標準輸出流是行緩衝的;在這種情況下,稍後寫入標準錯誤的文本可能會在較早時出現在終端上,如果標準輸出流的緩衝區不是還沒有完整)。

+0

我從來沒有對任何流的重點心臟..這是如何工作?我會用簡單的緩衝解釋。 – Voo 2012-02-05 01:54:57

+0

只是華麗的語言問題。固定更技術:) – 2012-02-05 01:58:16

相關問題