一卤恳、嵌套流
流對象被其他處理流的多次連接秸歧,稱為流的嵌套灾锯。
直接與數(shù)據(jù)源相連接的流是節(jié)點流
處理流連接節(jié)點流,提供附加性能
處理流可以被其它處理流繼續(xù)連接绰垂,以獲取需要的其它性能室奏。
處理流不可以與節(jié)點(數(shù)據(jù)源)直接連接
二、緩沖流
默認帶了8192個字符的緩沖區(qū)劲装,是為了提高性能胧沫,減少頻繁和硬盤進行io的次數(shù),
BufferedReader:處理流占业,字符輸入流绒怨,是Reader的子類提供了readLine方法
BufferedWriter:處理流,字符輸出流谦疾,是Writer的子類南蹂,提供了newLine() write(str)方法
三、轉換流
字符在計算機中以二進制編碼存儲念恍,字符的編碼規(guī)則有多種六剥。
在一個編碼規(guī)則下的所編碼的字符集合稱為該編碼的字符集。
對中文編碼的字符集有unicode峰伙、UTF-8仗考、GB2312、GBK词爬、GB18030等秃嗜。
例如:“漢”的各種字符集編碼如下(16進制表示)
unicode編碼:6c49
UTF-8編碼:e6b189
GBK編碼:baba
在Java中的字符一律采用unicode編碼,而在文件(或其它數(shù)據(jù)源)中存儲的字符編碼會有多種選擇顿膨。
因此當Java通過流對象讀寫字符時锅锨,必須將unicode編碼與其它編碼進行轉換。
FileReader和FileWriter兩個字符流直接采用平臺的默認字符集編碼和unicode進行轉換恋沃。
若默認字符集為GBK必搞,而文件的字符集為UTF-8,這時就無法正確讀寫文件囊咏。
InputStreamReader和OutputStreamWriter兩個字符流可以指定與unicode進行轉換的字符集編碼恕洲,因此這兩
個字符流更具靈活性。
1. InputStreamReader
InputStreamReader繼承了Reader梅割,它實現(xiàn)了Reader的抽象方法霜第。
InputStreamReader是字節(jié)流通向字符流的橋梁,它使用指定的字符集(charset)讀取字節(jié)并將其
解碼為unicode字符
2. OutPutStreamWriter
????OutputStreamWriter繼承了Writer户辞,它實現(xiàn)了Writer的抽象方法
????OutputStreamWriter是字符流通向字節(jié)流的橋梁泌类,這剛好與InputStreamReader相反。它使用指定
????的字符集(charset)將要寫入流中的unicode字符編碼成字節(jié)
四底燎、其他處理流
1. DataInputStream:處理流刃榨,可以直接讀取一些基本數(shù)據(jù)類型的數(shù)據(jù)
讀取的順序要與存入的順序一致弹砚,否則讀出的內(nèi)容是不準確的。
2. DataOutPutStream:處理流枢希,可以直接寫入一些基本數(shù)據(jù)類型的數(shù)據(jù)
這時桌吃,寫入的文件,看到寫入的內(nèi)容
五苞轿、序列化
1. 對象流
對象輸入流(ObjectInputStream):
ObjectInputStream in=newObjectInputStream(輸入流對象);
相應的方法:in.readObject();
對象輸出流(ObjectOutputStream):
ObjectOutputStream out=new ObjectOutputStream(輸出流對象);
相應的方法:out.writeObject(Object obj);
2. 序列化
序列化:就是將對象的內(nèi)容分解成字節(jié)流读存,以便存儲在文件中或在網(wǎng)絡上傳輸。
屬性的要求:非transient 非靜態(tài) 是可序列化類型(Serializable)
反序列化:就是打開并讀取字節(jié)流呕屎,且從該流中恢復該對象
沒有執(zhí)行過反序列化的類型對應的代碼塊及構造方法
能夠序列化的對象必須是Serializable類型,對應的類型必須實現(xiàn)Serializable接口
序列化類型中一般會要求提供一個serialVersionUID敬察,作用是保證讀(反序列化)和寫(序列化)的過程
中類型版本的一致性秀睛。如 寫的時候版本id為1 那么讀的時候版本id也必須是1,才能成功
注意:使用EOFException判斷文件是否讀取到末尾
問題描述:
用類ObjectOutputStream向文件寫讀對象時莲祸,碰到一個問題:新建一個文件蹂安,用輸出流ObjectOutputStream向文件連續(xù)寫幾個對象,關閉輸出流锐帜,然 后讀取田盈,這些對象都可以讀出;這時在向該文件增加對象缴阎,新寫的對象就讀不出了
問題出現(xiàn)的原因:
ObjectOutputStream建立后第一次寫入一個對象時允瞧, 會在對象數(shù)據(jù)前寫入一些標志的數(shù)據(jù)“AC ED 00 05”(用二進制方式查看打開),應該是流相關的信息蛮拔。當你關閉 ObjectOutputStream 后再重新打開往文件里面寫對象時(append方式)述暂,就會再一次把“AC ED 00 05”寫入文件,而這些信息并不是你寫入對象的數(shù)據(jù)建炫,所以當你用ObjectInputStream來讀取對象時畦韭,流會將除第一個“AC ED 00 05”以外的數(shù)據(jù)當作各個對象的數(shù)據(jù),造成無法解析肛跌,所以讀取時有一個java.io.StreamCorruptedException出現(xiàn)艺配。 這個可以通過編輯Info.dat來驗證,只要將“AC ED 00 05”刪除(第一個“AC ED 00 05”保留)就可以正常讀出后來加入的對象衍慎。 給出一個比較笨的解決方法: 在以后要添加新的對象到Info.dat時转唉,將里面原有的對象讀出放入ArrayList中,清空文件稳捆,再將對象集一次寫入酝掩。嘗試解決辦法:那個“AC ED 00 05”是 ObjectOutputStream.writeSystemHeader()寫進去的,你可以繼承ObjectOutputStream類眷柔,覆蓋這個方法期虾。 在你自己的writeSystemHeader()里判斷是不是第一次寫入一個文件原朝,如果是向一個文件大小不為零的文件追加的話,就調(diào)用 super.reset(),如果是第一次寫這個文件镶苞,不是追加喳坠,就調(diào)用super.writeSystemHeader()