2011-04-27 122 views
2

過去幾天我一直在閱讀Java中的流。在閱讀了很多內容之後,我開始明白,「流」這個名字是因爲與我們在「現實生活」中使用的詞相似而被選中的,例如水。而且沒有必要知道數據來自哪裏。如果我解釋錯了,請糾正。關於Java中流的問題

但我不明白這一點。當我在插座上說getOutputStreamgetInputStream時,我得到一個InputStream,我可以鏈接到任何我喜歡的東西。但是不是InputStream/OutputStream抽象類?我不知道如何正確解釋它,但我不明白,只通過調用該方法的套接字連接自動具有字節/字符可以流動的流/通道?什麼是實際上是一個InputStream/OutputStream?流是一種抽象真實來源的方式嗎?

我想我理解鏈接他們的各種方式,但我覺得我錯過了這個概念的核心。

由於缺乏正確的解釋方法,我會刪除問題,如果它不好。

謝謝你的時間。

回答

3

InputStream/OutputStream是,很好,抽象。它們爲讀取/寫入字節或字節組提供了一些基本的API,而不會暴露實際的實現。我們以OutputStream爲例:

OutputStream通過公共API接收一堆字節。你實際上並不知道(並關心)這些字節後發生了什麼:他們是發送。真正的實現可以:將它們附加到文件中,忽略它們(Apache Commons中的NullOutputStream),將它們保存在內存中或...通過套接字發送。

這是當你調用Socket.getOutputStream()會發生什麼:你一些實施OutputStream,只是不小心,它是依賴於實現和具體。當你向這個流發送字節時,底層實現將使用TCP/IP或UDP來推送它們。事實上,TCP/IP本身就是一個流協議,儘管它在數據包/幀上運行。

這種情況是類似的InputStream - 你從一些執行從套接字。當你詢問流的幾個字節時,底層的InputStream實現將詢問OS套接字相同的字節量,可能會阻塞。但這是繼承的真正樂趣:你不在乎!只要使用這些流你想要的任何方式,鏈接,緩衝等。

+0

太好了,謝謝。那就是我所追求的,實際上我應該停止關注發生的事情。 – LuckyLuke 2011-04-27 21:45:23

3

當您調用getInputStream時,套接字將返回一些具體子類InputStream的實例。通常你不用擔心返回對象的確切類。因爲它是一個InputStream,你只需要這樣工作。 (子類甚至可能是套接字類的私有嵌套類。)

3

InputStream確實是一個抽象。每次都可以使用流概念的不同實現。但是流的用戶不需要知道確切的實現是什麼。

Socket的情況下,該實現是SocketInputStream延伸FileInputStream

3

我不認爲這是一個壞問題。你說得很對,這些流將數據的來源複雜化,並使其統一起來。因此,您可以編寫從文件或套接字讀取的代碼,並且該代碼看起來幾乎完全相同。這意味着你通常不得不編寫更少的代碼。

當您從Socket獲得InputStream時,您可以訪問到達該套接字的任何數據。從這個流中讀取數據時,通常會提供一個字節數組,並要求流爲它填充。它將讀取儘可能多的數據或填充緩衝區。這取決於你如何處理這個字節數組中的數據。

對於任何類型的Socket IO,雖然已經說過關於Streams的所有內容,但是Java套接字API是相當古老的,並且有一些非常好的替代方案可用於包裝它並更易於使用。我強烈建議使用Netty,您可以使用它來忘記流並關注POJO以及如何對它們進行編碼和解碼。