2009-08-01 58 views
70

編程世界中的流是什麼?我們爲什麼需要它?什麼是流?

如果可能,請在類比的幫助下進行解釋。

+8

這是http://stackoverflow.com/questions/507747/can-you-explain-the-concept-of-streams的副本。 – 2009-08-01 11:47:51

回答

101

流表示一系列對象(通常是字節,但不一定是這樣),它們可以按順序訪問。流上的典型操作:

  • 讀取一個字節。下次你閱讀,你會得到下一個字節,等等。
  • 從流讀取幾個字節到一個數組
  • 求(移動你的當前位置的數據流中,以便下次你讀你得到新的位置字節時間)
  • 寫一個字節
  • 寫幾篇字節從一個數組流入流
  • 從流中跳過字節(這類似於讀取,但您忽略數據,或者如果您更喜歡它就像查找,但只能向前)
  • 將字節推回到輸入流(這就像讀取「撤消」一樣 - 你將幾個字節推回到流中,以便下次讀取t時帽子就是你會看到的。它是解析器有時候是有用的,因爲是:
  • PEEK(看個字節不讀它們,讓它們還在那裏流中稍後閱讀)

特定流可能支持讀取(在哪種情況下它是「輸入流」),寫入(「輸出流」)或兩者。並非所有的流都是可搜索的。

推回相當少見,但您可以通過將實際輸入流包裝到另一個包含內部緩衝區的輸入流中,將其添加到流中。讀取來自緩衝區,如果你推回來,那麼數據被放入緩衝區。如果緩衝區中沒有任何內容,則推回流將從實際流中讀取。這是一個「流適配器」的簡單示例:它位於輸入流的「結尾」,它是一個輸入流本身,它做了額外的事情,原始流沒有。流是一個有用的抽象,因爲它可以描述文件(這是真正的數組,因此尋求是直接的),但也終端輸入/輸出(這是不可搜索,除非緩衝),套接字,串行端口等。所以你可以編寫代碼說:「我想要一些數據,我不在乎它來自哪裏或它是如何到達這裏的」,或者「我將生成一些數據,完全取決於我的調用者它發生了什麼」。前者接受輸入流參數,後者接受輸出流參數。

我能想到的最好的比喻是流是一條傳送帶向你走來或從你(或有時兩者)帶走。你從輸入流中取出東西,把東西放在輸出流上。一些傳送帶可以被認爲是從牆上鑽出來的 - 它們不是可追求的,閱讀或寫作是一次性交易。有些傳送帶擺放在你的面前,你可以隨意選擇你想要讀/寫的小溪中的下落位置 - 這正在尋找。

正如IRBMe所說,儘管最好從流程的角度來考慮它所提供的操作(從實現到實現有所不同,但有很多共同點),而不是物理比喻。流是「你可以讀或寫的東西」。當你開始連接流適配器時,你可以把它們想象成一個盒子,裏面有一個傳送帶,一個傳送帶,連接到其他流,然後盒子對數據進行一些轉換(壓縮或更改UNIX換行符到DOS的,或其他)。管道是隱喻的另一個徹底測試:那就是你創建一對流的地方,這樣你寫入其中的任何東西都可以被讀出。認爲蟲洞:-)

+1

迄今爲止我讀過的最好的解釋。再加上它在SICP中所說的話(「流處理可以讓我們對沒有使用任務或可變數據的狀態進行建模的系統進行建模。」),我想我終於明白了。謝謝! – 2016-10-08 17:04:50

24

流已經是一個比喻,是一個比喻,所以真的沒有必要去提供另一個。你可以把它想象成一個管道,裏面有水流,水是實際的數據,管道是水流。如果流是雙向的,我想這是一種雙向管道。它基本上是一種常見的抽象,它被放置在一個或兩個方向上有數據流或數據序列的地方。

在諸如C#,VB.Net,C++,Java等語言中,流隱喻用於很多事情。有文件流,您可以在其中打開文件並可以從流中讀取或寫入;有一些網絡流可以讀取和寫入流,讀取和寫入基礎的已建立網絡連接。僅用於寫入的流典型地稱爲輸出流,如在this示例中那樣,並且類似地,僅用於讀取的流被稱爲輸入流,如在this示例中那樣。

流可以執行數據的轉換或編碼(例如,在.Net中使用SslStream,例如,會吞掉SSL協商數據並將其隱藏起來; TelnetStream可能會隱藏Telnet協商,但可以訪問數據; Java中的A ZipOutputStream允許您寫入zip文件中的文件,而不必擔心zip文件格式的內部問題。

您可能會發現的另一個常見問題是文本流,它允許您編寫字符串的字節,或者某些語言​​提供的二進制流,允許您編寫基本類型。您在文本流中發現的常見事項是字符編碼,您應該知道這一點。

某些流也支持隨機訪問,例如this示例。另一方面,網絡流出於顯而易見的原因不會。

UNIX like操作系統也支持帶有程序輸入和輸出的流模型,如所述。

5

除了上面提到的東西之外,還有一種不同類型的流 - 如函數式編程語言(如Scheme或Haskell)中定義的 - 一種可能無限的數據結構,由一些按需函數生成。

4

另一個比喻:你不能在流中游泳,這就是爲什麼你可以從流中取出下一位,字節,字符串或對象,而已經讀取的數據被刪除。單程票...或基本上只是一個隊列沒有存儲持久性。

那麼我們需要排隊嗎?你決定。

+0

這意味着,在一條河流中,你必須前進不能倒退。另外之前的數據被刪除,因爲你往前保存了內存? – 2016-03-08 07:05:30

3

「流」這個詞已被選中,因爲它代表了(在現實生活中)與我們在使用它時傳達的意義非常相似的意思。

開始思考與水流類比。您會收到持續的數據流,就像水在河中不斷流動一樣。你不一定知道數據來自哪裏,大多數情況下你不需要;無論是來自文件,套接字還是其他來源,它都沒有(不應該)真的很重要。這與接收水流非常相似,因此您不需要知道它來自哪裏;無論是來自湖泊,噴泉還是任何其他來源,它都沒有(不應該)真的很重要。 source