2013-04-03 52 views
5

我想寫入一個套接字。從閱讀有關網絡IO,在我看來是寫的最佳方式是做這樣的事情:將BufferedWriter和BufferedOutputStream一起使用是否過分矯枉過正?

OutputStream outs=null; 
BufferedWriter out=null; 
out = 
    new BufferedWriter(
    new OutputStreamWriter(new BufferedOutputStream(outs),"UTF-8")); 

BufferedWriter將緩衝輸入到其建議的OutputStreamWriter,因爲它阻止了作家從爲每個角色啓動編碼器。

然後BufferedOutputStream將緩衝來自Writer的字節,以避免一次一個字節可能放到網絡上。

它看起來有點像矯枉過正,但它似乎都有幫助? 感謝您的幫助..

編輯:根據JavaDoc上OutputStreamWriter

寫入中的每一個調用()方法會導致在給定的字符(或多個)將被調用的編碼轉換器。生成的字節在寫入底層輸出流之前會在緩衝區中累積。這個緩衝區的大小可以被指定,但是默認情況下它對於大多數目的來說足夠大。請注意,傳遞給write()方法的字符不會被緩衝。

爲了獲得最高的效率,可以考慮在BufferedWriter中封裝一個OutputStreamWriter,以避免頻繁的轉換器調用。例如:

​​

回答

1

的的BufferedWriter將緩衝輸入到OutputStreamWriter,後者被推薦的,因爲它防止了從作家啓動每個字符的編碼器。

由誰推薦,並在什麼情況下? 「啓動編碼器」是什麼意思?無論如何,你是否一次向作家寫了一個單獨的角色? (我們不知道很多關於你如何使用作家......這可能是很重要的。)

的的BufferedOutputStream將隨後從Writer緩衝區的字節數,以避免把一個字節的時間可能到網絡。

是什麼讓你覺得它會一次寫入一個字節?我認爲OutputStreamWriter不太可能一次寫入一個字節給底層的作者,除非你真的一次寫了一個字符。

此外,我希望網絡輸出流使用類似Nagle's algorithm的東西,以避免發送單字節數據包。

與以往一樣,您應該根據證據來做到這一點......您是否已經做過任何有和沒有這些緩衝層的測試?

編輯:只是爲了澄清,我不是說緩衝類是無用的。在某些情況下,他們是絕對是正確的路要走。我只是說,與全部優化,他們不應該盲目使用。您應該考慮您要優化的內容(處理器使用情況,內存使用情況,網絡使用情況等)和衡量標準。這裏有很多重要的因素 - 其中最重要的是寫作模式。如果你已經在寫「大塊頭」 - 寫大塊的字符數據 - 那麼緩衝區的影響相對較小。如果你實際上是一次向作者寫一個單獨的角色,那麼他們會更加重要。

+0

感謝您的回覆。從OutputStreamWriter的javadoc中,「write()方法的每次調用都會導致編碼轉換器在給定字符上被調用。生成的字節在寫入底層輸出流之前會在緩衝區中累積。這個緩衝區可以被指定,但是默認情況下它對於大多數目的來說足夠大了。注意傳遞給write()方法的字符沒有被緩衝。爲了獲得最高的效率,可以考慮在BufferedWriter中包裝一個OutputStreamWriter,以避免頻繁的轉換器調用「。 OP中的整個報價編輯 – Bruce 2013-04-03 22:24:47

+0

@Bruce:*考慮*,當然。這與推薦*不一樣。我會測試它。儘管如此,我仍然很驚訝地發現它在大多數情況下都有顯着的不同。 – 2013-04-03 22:26:10

+0

感謝您的有用答覆。是的,我應該測試它。它實際上是我爲面試做的編程測試的一部分,我想知道那種默認的正確解決方案是什麼,或者至少有一個沒有明顯錯誤。 – Bruce 2013-04-03 22:31:19

7

Buffered *類的用途是將小寫操作合併爲一個較大的寫操作,從而減少系統調用次數並提高吞吐量。由於BufferedWriter已經將緩衝區中的寫入收集起來,然後將緩衝區中的字符轉換爲另一個緩衝區,並且在一次操作中將該緩衝區寫入底層的OutputStream,因此OutputStream已經被大寫操作調用。因此,BufferedOutputStream找不到任何組合,並且只是多餘的。另外,同樣可以適用於BufferedWriter:緩衝只有在寫者一次只傳遞幾個字符時纔有幫助。如果你知道調用者只寫很大的字符串,BufferedWriter將找不到任何可以組合的東西,也是多餘的。

+1

感謝您的回覆。這澄清了很多。我覺得我覺得這是一種糟糕的形式,沒有緩衝,但你說的話有很大的意義。 – Bruce 2013-04-03 22:42:10

1

是的,它是矯枉過正。來自Javadoc for OutputStreamWriter:「write()方法的每次調用都會導致編碼轉換器在給定字符上被調用。生成的字節在寫入底層輸出流之前在緩衝區中累積。」

+0

@downvoter你在這裏與Javadoc爭吵。哪部分是完全錯誤的? – EJP 2013-07-10 09:30:49

+0

(我不是downvoter!)我認爲這是一個完美,簡潔的答案!很明顯,通過_wrapping_和一個緩衝區,我們確保編碼器只有在字符累積時才被觸發,並且由於它有一個內部緩衝區,當緩衝區滿時它只會觸發底層寫入。 – SusanW 2016-08-16 18:30:33

相關問題