Java所有的I/O機制都是基于數據流進行輸入輸出,這些數據流表示了字符或者字節數據的流動序列。Java的I/O流提供了讀寫數據的標準方法。任何Java中表示數據源的對象都會提供以數據流的方式讀寫它的數據的方法。
標準輸入輸出,文件的操作,網絡上的數據流,字符串流,對象流,zip文件流等等,java中將輸入輸出抽象稱為流,就好像水管,將兩個容器連接起來。將數據沖外存中讀取到內存中(供Java程序使用)的稱為輸入流,將數據從內存寫入外存中的稱為輸出流。
流是一個很形象的概念,當程序需要讀取數據的時候,就會開啟一個通向數據源的流,這個數據源可以是文件,內存,或是網絡連接。類似的,當程序需要寫入數據的時候,就會開啟一個通向目的地的流。
流是一組有順序的,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。即數據在兩設備間的傳輸稱為流,流的本質是數據傳輸,根據數據傳輸特性將流抽象為各種類,方便更直觀的進行數據操作。
流的分類:
流的分類,Java的流分類比較豐富,剛接觸的人看了后會感覺很暈。流分類的方式很多:
1、按照輸入的方向分,輸入流和輸出流,輸入輸出的參照對象是Java程序。
2、按照處理數據的單位不同分,字節流和字符流,字節流讀取的最小單位是一個字節(1byte=8bit),而字符流一次可以讀取一個字符(1char = 2byte = 16bit)。
3、按照功能的不同分,分節點流和處理流,節點流是直接從一個源讀寫數據的流(這個流沒有經過包裝和修飾),處理流是在對節點流封裝的基礎上的 一種流,FileInputStream是一個節點流,可以直接從文件讀取數據,但是BufferedInputStream可以包裝 FileInputStream,使得其有緩沖功能。
流的類結構圖:
Java中“流”的概念與簡介
字節流與字符流:
字符流的由來: 因為數據編碼的不同,而有了對字符進行高效操作的流對象。本質其實就是基于字節流讀取時,去查了指定的碼表。 字節流和字符流的區別:
讀寫單位不同:字節流以字節(8bit)為單位,字符流以字符為單位,根據碼表映射字符,一次可能讀多個字節。
處理對象不同:字節流能處理所有類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。
結論:只要是處理純文本數據,就優先考慮使用字符流。除此之外都使用字節流。
這里需要提到的一句是:一個英文字符的長度是1byte,而漢字的長度是2byte. 如果我們把英漢混合的文檔統一按照字節流處理,就會出現分割混亂,出現亂碼。這是,我們需要使用字符流來處理。這就是為什么在處理文檔的時候,都要把inputstream放到FileReader中。
方向性:
流分為輸入流和輸出流。但這都是相對的。特別是在Hadoop的序列化時,總是不知道到底使用輸入流還是輸出流。這里,我們可以做個區分:
序列化,就是把數據做字節流處理。而字節流只是一種存儲形式。他不會被程序識別,需要把字節流反序列化為java識別的對象,才可以被java程序識別。所以,序列化就是字節流化,就是從java代碼或內存中輸出到外存。而反序列化就是對象化,就是從外存中將字節流數據轉化為程序識別的對象。