2014-10-11 61 views
2

我目前在一個帶有OutputStream的客戶端 - 服務器應用程序中使用Java套接字,而不是BufferedOutputStream(並且對於輸入流是相同的)。使用緩衝流發送對象?

客戶端和服務器交換序列化對象(writeObject()方法)。

在這種情況下使用BufferedOutputStream和BufferedInputStream是否有意義(更快)?

當我不得不刷新或不應該寫一個flush()語句?

回答

7

在這種情況下使用BufferedOutputStream和BufferedInputStream是否有意義(更快)?

事實上,它可能有意義。

對象流實現在內部將它與給定的流打包在一個名爲BlockDataOutputStream的私有類中,該類具有緩衝功能。如果你自己包裝流,你將有兩個級別的緩衝......這可能會使性能更差。

當我不得不刷新或者我不應該寫一個flush()語句?

是的,沖洗可能是必要的。但這樣做沒有普遍的答案。

  • 一方面,如果你頻繁刷新,你會產生額外的網絡流量。另一方面,如果在需要時不刷新,服務器可能會停止等待客戶端已寫入但未刷新的對象。

您需要找到這兩個症狀之間的折衷......這取決於您的應用程序的客戶端/服務器交互模式;例如消息模式是同步的(例如消息/響應)還是異步的(例如消息流)。


1 - 要在此肯定的,你需要做一些法醫檢測:1)測量系統性能,以及2)確定的系統調用是由什麼,當網絡數據包被髮送。對於一般的答案,您需要對許多用例重複此操作。我還建議您自己查看Java庫代碼以確認我的(簡短)閱讀。

2 - 大概只有一點點差,但精心設計的基準便拿起一個小的性能差異。


UPDATE

寫了上之後,我發現這個問答& A - Performance issue using Javas Object streams with Sockets - 這似乎表明,使用BufferedInputStream/BufferedOutputStream幫助。但是,我不確定報告的性能改進是否是1)真實的(即不是熱身僞影),2)由於緩衝。這可能只是由於添加了flush()呼叫。 (爲什麼:因爲刷新可能會導致網絡堆棧更快地推送數據。)

+0

謝謝。我正在使用同步消息模式。在這種情況下哪種沖洗原理好? – machinery 2014-10-12 08:46:32

+0

如果我會使用ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));並且對於輸入流也是一樣的,我還需要在最後關閉BufferedOutputStream,還是通過關閉ObjectOutputStream和套接字來自動完成? – machinery 2014-10-12 08:53:19

+0

最後但並非最不重要,我必須調用objectOutputStream或BufferedOutputStream上的flush()嗎? – machinery 2014-10-12 08:56:12

0

我認爲這些鏈接可以幫助您:

What is the purpose of flush() in Java streams?

flush方法刷新輸出流並強制任何緩衝的輸出字節被寫出。 flush的一般契約是,調用它表明,如果先前寫入的任何字節已被輸出流的實現緩衝,則應立即將這些字節寫入其預定目標。

How java.io.Buffer* stream differs from normal streams?

在內部使用和,而不是從基本輸入流足夠的字節被讀出以填充緩衝器單獨讀取字節的緩衝器陣列。這通常會導致性能更快,因爲底層輸入流需要更少的讀取。

http://www.oracle.com/technetwork/articles/javase/perftuning-137844.html

作爲開始討論的方法,下面是關於如何加快I/O的一些基本規則:1.Avoid訪問磁盤。 2.避免訪問底層操作系統。 3.避免方法調用。 4.避免單獨處理字節和字符。

因此,使用緩衝流通常會加快IO進程的速度,因爲read()在後臺執行的次數更少。