標籤:
流的大家族
流(stream)的概念:
源於UNIX中管道(pipe)的概念。在UNIX中,管道是一條不間斷的位元組流,用來實現程式或進程間的通訊,或讀寫外圍裝置、外部檔案等。
一個流,必有源端和目的端,它們可以是電腦記憶體的某些地區,也可以是磁碟檔案,甚至可以是Internet上的某個URL。
流的方向是重要的,根據流的方向,流可分為兩類:輸入資料流和輸出資料流。
使用者可以從輸入資料流中讀取資訊,但不能寫它。相反,對輸出資料流,只能往輸入資料流寫,而不能讀它。
實際上,流的源端和目的端可簡單地看成是位元組的生產者和消費者,對輸入資料流,可不必關心它的源端是什麼,只要簡單地從流中讀資料,而對輸出資料流,也可不知道它的目的端,只是簡單地往流中寫資料。
形象的比喻——水流 ,檔案
======程式 : 檔案和程式之間串連一個管道,水流就在之間形成了,自然也就出現了方向:可以流進,也可以流出.便於理解,這麼定義流: 流就是一個管道裡面有流水,這個管道串連了檔案和程式。
java.io包中的類對應兩類流
一類流直接從指定的位置(如磁碟檔案或記憶體地區)讀或寫,這類流稱為結點流(node stream),其它的流則稱為過濾器(filters)。
過濾器輸入資料流往往是以其它輸入資料流作為它的輸入源,經過過濾或處理後再以新的輸入資料流的形式提供給使用者,過濾器輸出資料流的原理也類似。
Java中的流,可以從不同的角度進行分類。
按照數據流的方向不同可以分為:輸入資料流和輸出資料流。
按照處理資料單位不同可以分為:位元組流和字元流。
按照實現功能不同可以分為:節點流和處理流。
輸出資料流:
輸入資料流:
因此輸入和輸出都是從程式的角度來說的。
位元組流:一次讀入或讀出是8位二進位。
字元流:一次讀入或讀出是16位二進位。
位元組流和字元流的原理是相同的,只不過處理的單位不同而已。尾碼是Stream是位元組流,而尾碼是Reader,Writer是字元流。
節點流:直接與資料來源相連,讀入或讀出。
直接使用節點流,讀寫不方便,為了更快的讀寫檔案,才有了處理流。
處理流:與節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。
Jdk提供的流繼承了四大類:InputStream(位元組輸入資料流),OutputStream(位元組輸出資料流),Reader(字元輸入資料流),Writer(字元輸出資料流)。
以下是java中io中常用的流。
如果現在你還很迷茫,那請你繼續讀下面的文字,你會豁然開朗!
一、什麼是流?
流就是位元組序列的抽象概念,能被連續讀取資料的資料來源和能被連續寫入資料的接收端就是流,流機制是Java及C++中的一個重要機制,通過流我們可以自由地控制檔案、記憶體、IO裝置等資料的流向。而IO流就是用於處理裝置上的資料,如:硬碟、記憶體、鍵盤錄入等。IO流根據處理類型的不同可分為位元組流和字元流,根據流向的不同可分為輸入資料流和輸出資料流。
二、位元組流和字元流的區別:
字元流,因為檔案編碼的不同,就有了對字元進行高效操作的字元流對象,它的原理就是基於位元組流讀取位元組時去查了指定的碼錶。它和位元組流的區別有兩點:1.在讀取資料的時候,位元組流讀到一個位元組就返回一個位元組,字元流使用了位元組流讀到一個或多個位元組(一個中文對應的位元組數是兩個,在UTF-8碼錶中是3個位元組)時,先去查指定的編碼錶,再將查到的字元返回;2.位元組流可以處理所有類型的資料,如jpg、avi、mp3、wav等等,而字元流只能處理字元資料。所以可以根據處理的檔案不同考慮使用位元組流還是字元流,如果是純文字資料可以優先考慮字元流,否則使用位元組流。
各個字元流與位元組流的拆分!
位元組輸入資料流:
位元組輸出資料流:
字元輸入資料流:
字元輸出資料流:
簡單介紹其:
對檔案進行操作:FileInputStream(位元組輸入資料流),FileOutputStream(位元組輸出資料流),FileReader(字元輸入資料流),FileWriter(字元輸出資料流)
對管道進行操作:PipedInputStream(位元組輸入資料流),PipedOutStream(位元組輸出資料流),PipedReader(字元輸入資料流),PipedWriter(字元輸出資料流)
PipedInputStream的一個執行個體要和PipedOutputStream的一個執行個體共同使用,共同完成管道的讀取寫入操作。主要用於線程操作。
位元組/字元數組:ByteArrayInputStream,ByteArrayOutputStream,CharArrayReader,CharArrayWriter是在記憶體中開闢了一個位元組或字元數組。
Buffered緩衝流::BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,是帶緩衝區的處理流,緩衝區的作用的主要目的是:避免每次和硬碟打交道,提高資料訪問的效率。
轉化流:InputStreamReader/OutputStreamWriter,把位元組轉化成字元。
資料流:DataInputStream,DataOutputStream。
因為平時若是我們輸出一個8個位元組的long類型或4個位元組的float類型,那怎麼辦呢?可以一個位元組一個位元組輸出,也可以把轉換成字串輸出,但是這樣轉換費時間,若是直接輸出該多好啊,因此這個資料流就解決了我們輸出資料類型的困難。資料流可以直接輸出float類型或long類型,提高了資料讀寫的效率。
列印流:printStream,printWriter,一般是列印到控制台,可以進行控制列印的地方。
物件流程:ObjectInputStream,ObjectOutputStream,把封裝的對象直接輸出,而不是一個個在轉換成字串再輸出。
序列化流:SequenceInputStream。
對象序列化:把對象直接轉換成二進位,寫入介質中。
使用物件流程需要實現Serializable介面,否則會報錯。
而若用transient關鍵字修飾成員變數,不寫入該成員變數,若是參考型別的成員變數為null,值類型的成員變數為0.
JAVA位元組流
- FileInputStream和FileOutputStream
這兩個類屬於結點流,第一個類的源端和第二個類的目的端都是磁碟檔案,它們的構造方法允許通過檔案的路徑名來構造相應的流。如:
FileInputStream infile = new FileInputStream("myfile.dat");
FileOutputStream outfile = new FileOutputStream("results.dat");
要注意的是:構造FileInputStream, 對應的檔案必須存在並且是可讀的,而構造FileOutputStream時,如輸出檔案已存在,則必須是可覆蓋的。
- BufferedInputStream和BufferedOutputStream
它們是過濾器流,其作用是提高輸入輸出的效率。
- DataInputStream和DataOutputStream
這兩個類建立的對象分別被稱為資料輸入流和資料輸出資料流。這是很有用的兩個流,它們允許程式按與機器無關的風格讀寫Java資料。所以比較適合於網路上的資料轉送。這兩個流也是過濾器流,常以其它流如InputStream或OutputStream作為它們的輸入或輸出。
Java的字元流
字元流主要是用來處理字元的。Java採用16位的Unicode來表示字串和字元,對應的字元流按輸入和輸出分別稱為readers和writers。
- InputStreamReader和OutputStreamWriter
在構造這兩個類對應的流時,它們會自動進行轉換,將平台預設的編碼集編碼的位元組轉換為Unicode字元。對英語環境,其預設的編碼集一般為ISO8859-1。
- BufferedReader和BufferedWriter
這兩個類對應的流使用了緩衝,能大大提高輸入輸出的效率。這兩個也是過濾器流,常用來對InputStreamReader和OutputStreamWriter進行處理。
本文借鑒了
http://blog.csdn.net/yuebinghaoyuan/article/details/7388059
http://www.cnblogs.com/pepcod/archive/2013/01/20/2913435.html
瘋狂Java學習筆記(54)----------詳解Java IO(全面)