2012-02-22 26 views
6

今天,我無意中聽到關於System.out.print()的爭執。一個人聲稱,由於print()不包括終止\n,它寫入的緩衝區最終將填滿並開始丟失數據。另一個人聲稱他們一直在使用System.out.print()來處理所有的Java程序,並且從未遇到過這個問題。Java的System.out.print()緩衝區會永久存在,直到println()?

第一人選對不對?如果stdout已滿,System.out.print()是否可能開始阻塞或丟棄數據?有沒有會導致這種情況的代碼示例?

+2

使用'System.setOut()'來代替'System.out'與一個自定義流,拋出一個異常 – paislee 2012-02-22 20:41:34

+4

他們都是錯誤的。 '\ n'與它無關,調用'.close()'或'.flush()'與處理流或正在丟失的內容有關。 – 2012-02-22 20:44:59

回答

11

System.out.print使用的緩衝區填滿時,輸出寫入文件(或連接到程序標準輸出流的終端或其他數據目標),導致空緩衝區。寫入輸出而不關心緩衝區大小是正常的使用。您永遠不會崩潰或阻止您的程序,或因未撥打flush而丟失數據。

如果您需要立即在程序外部提供數據,則只需明確呼叫flush即可。例如,如果您的程序正在與另一個程序來回交換數據,並且您正在向該程序發送請求並等待該程序的回覆,則需要在發送請求後調用flush以確保其他程序收到它。同樣,如果您的程序(或運行它的計算機)崩潰,則只能保證輸出到上次您撥打flush時的輸出。

如果將流設置爲自動刷新,則寫入換行符(明確或通過println)與調用flush一樣好。調用close也會調用flush(這就是爲什麼close可能會拋出一個IOException:它可能不得不寫入數據並且無法(例如,因爲該流連接到完整磁盤上的文件)。

請注意,刷新緩衝區可能會導致程序阻塞,如果連接的流不是立即準備好接收數據(例如,當數據傳輸到另一個不立即讀取其輸入的程序時)。由於緩衝區可以隨時刷新(因爲緩衝區恰好已滿),所以使用非空參數調用print可能會被阻塞。請參閱buffered streams tutorialjava.io.PrintStream class的文檔。