[TOC]
IO流的本質(zhì)
本地設(shè)備和不同設(shè)備之間數(shù)據(jù)的傳輸
IO流的分類
按照數(shù)據(jù)類型分類
字節(jié)流: 一般針對二進(jìn)制文件 【視頻,音頻,圖片】
字符流: 一般針對文本文件 【xml,json,html,txt.md...】
按照流向分
輸入流: 從外界到內(nèi)存
輸出流: 從內(nèi)存到外界
綜合分類
字節(jié)流
字節(jié)輸入流 InputStream
字節(jié)輸出流 OutputStream
字符流
字符輸入流 Reader
字符輸出流 Writer
流的操作的三要素:
1.數(shù)據(jù)源: 數(shù)據(jù)需要從哪里到內(nèi)存?
2.目的地: 數(shù)據(jù)從內(nèi)存到哪里去?
3.交通工具:
a.弄明白到底需要輸入流還是輸出流,也有可能兩個都需要
b.根據(jù)確定的流向在IO流框架中選取自己認(rèn)為最適合的流
編碼: 字符/字符數(shù)組/字符串 --> 二進(jìn)制
解碼: 二進(jìn)制 --> 字符/字符數(shù)組/字符串
編碼表: 將字符轉(zhuǎn)換成對應(yīng)數(shù)字的一張對照表
編碼處理
編碼的處理:
1.字符
2.字符串
getBytes("UTF-8");
new String(bys, "UTF-8")
3.文本文件 流
OutputStreamWriter(轉(zhuǎn)換流,是字符流通向字節(jié)流的橋梁,可使用指定的 charset 將要寫入流中的字符編碼成字節(jié)。它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺默認(rèn)字符集編碼。)
構(gòu)造方法
OutputStreamWriter(OutputStream out) 創(chuàng)建使用默認(rèn)字符編碼的字符輸出轉(zhuǎn)換流
OutputStreamWriter(OutputStream out, Charset cs) 創(chuàng)建使用cs字符集的字符輸出轉(zhuǎn)換流
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 創(chuàng)建使用enc字符集編碼器的
OutputStreamWriter(OutputStream out, String charsetName) 創(chuàng)建使用指定字符集的
IO流框架
IO流框架總結(jié)
普通IO / NIO
字節(jié)流
字節(jié)流
字節(jié)流是萬能流,但是在處理字符方面有時候不太方便,一般用來處理二進(jìn)制文件
字節(jié)輸入流
--InputStream
int available() 返回流中可用的字節(jié)數(shù)
void close() 關(guān)閉此輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源。
int read() 讀取一個字節(jié)
int read(byte[] b) 讀取一個字節(jié)數(shù)組
int read(byte[] b, int off, int len) 讀取字節(jié)數(shù)組的一部分
long skip(long n) 跳過多n個字節(jié)讀取
--FileInputStream
FileInputStream(File file)
通過打開一個到實(shí)際文件的連接來創(chuàng)建一個 FileInputStream,該文件通過文件系統(tǒng)中的 File 對象 file 指定。
FileInputStream(FileDescriptor fdObj)
通過使用文件描述符 fdObj 創(chuàng)建一個 FileInputStream,該文件描述符表示到文件系統(tǒng)中某個實(shí)際文件的現(xiàn)有連接。
FileInputStream(String name)
通過打開一個到實(shí)際文件的連接來創(chuàng)建一個 FileInputStream,該文件通過文件系統(tǒng)中的路徑名 name 指定。
-- BufferedInputStream
能夠提高讀寫效率
注意:
1.作為輸出流,文件可以不存在,會自動創(chuàng)建,作為輸入流,文件必須存在
2.處理中文的時候不方便
字節(jié)輸出流
--OutputStream
void close() 關(guān)閉此輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源。
void flush() 將數(shù)據(jù)從內(nèi)存中刷新到文件系統(tǒng)中
void write(byte[] b) 寫一個字節(jié)數(shù)組
void write(byte[] b, int off, int len) 寫一個字節(jié)數(shù)組的一部分
abstract void write(int b) 寫一個字節(jié)
1.針對字節(jié)流可以不使用flush,針對字符流必須flush,建議都要flush
2.close釋放流的資源,同時自帶flush
--FileOutputStream
FileOutputStream(File file)
創(chuàng)建一個向指定 File 對象表示的文件中寫入數(shù)據(jù)的文件輸出流。
FileOutputStream(File file, boolean append)
創(chuàng)建一個向指定 File 對象表示的文件中寫入數(shù)據(jù)的文件輸出流。
FileOutputStream(FileDescriptor fdObj)
創(chuàng)建一個向指定文件描述符處寫入數(shù)據(jù)的輸出文件流,該文件描述符表示一個到文件系統(tǒng)中的某個實(shí)際文件的現(xiàn)有連接。
FileOutputStream(String name)
創(chuàng)建一個向具有指定名稱的文件中寫入數(shù)據(jù)的輸出文件流。
FileOutputStream(String name, boolean append)
創(chuàng)建一個向具有指定 name 的文件中寫入數(shù)據(jù)的輸出文件流。
--BufferedOutputStream
能夠提高讀寫效率
注意:
在不同的操作系統(tǒng)中對換行符的支持不一樣
Windows \r\n
Linux \n
Mac \r
1.字節(jié)流在處理換行符的方面不方便
2.帶append參數(shù)的表示追加寫入
字符流
字符流
字符輸入流
Reader
...方法與字節(jié)輸入流一致
轉(zhuǎn)換流: InputStreamReader
1.處理編碼
2.將字節(jié)流轉(zhuǎn)化成字符流
FileReader是InputStreamReader子類,用來讀取字符文件的便捷類
高效緩沖字符輸入流 BufferedReader
readLine() 讀取一行
字符輸出流
Writer
...方法與字節(jié)輸出流一致
轉(zhuǎn)換流: OutputStreamWriter
1.處理編碼
2.將字節(jié)流轉(zhuǎn)化成字符流
FileWriter是OutputStreamWriter子類,用來寫入字符文件的便捷類
高效緩沖字符輸出流 BufferedWriter
newLine() 寫一個換行符
文件拷貝方式
文件拷貝的方式和原理:
1.FileInputStream/FileOutputStream一次性讀取一個字節(jié)
2.FileInputStream/FileOutputStream一次性讀取一個字節(jié)數(shù)組
3.BufferedInputStream/BufferedOutputStream一次性讀取一個字節(jié)
4.BufferedInputStream/BufferedOutputStream一次性讀取一個字節(jié)數(shù)組
5.FileReader/FileWriter一次性讀取一個字符
6.FileReader/FileWriter一次性讀取一個字符數(shù)組
7.BufferedReader/BufferedWriter一次性讀取一個字符
8.BufferedReader/BufferedWriter一次性讀取一個字符數(shù)組
9.BufferedReader/BufferedWriter一次性讀取一行
至少有九種方式拷貝文件
使用字節(jié)流實(shí)現(xiàn)文件拷貝
通過這里我們需要了解計(jì)算機(jī)是如何處理中文的?
首先讀取一個字節(jié),如果人為沒有轉(zhuǎn)換
那么系統(tǒng)會根據(jù)當(dāng)前的編碼表來處理中文 [中文的第一個數(shù)一般是負(fù)數(shù)]
如果是正數(shù),直接轉(zhuǎn)換成對應(yīng)碼表的字符
如果是負(fù)數(shù)
判斷編碼表,假設(shè)是GBK,會等待下一個字節(jié)一起轉(zhuǎn)換成對應(yīng)的字符
如果是UTF-8,就會等待下兩個字節(jié)一起轉(zhuǎn)換成對應(yīng)的字符
亂碼原因:
1.人為轉(zhuǎn)換
2.服務(wù)器和客戶端編碼表不一致
3.服務(wù)器系統(tǒng)編碼和人為編碼不一致
4.URL編碼和人為解碼不一致
異常
java.io.FileNotFoundException
產(chǎn)生原因:
1.文件盤符不存在
2.文件路徑父目錄不存在
java.io.IOException: Stream Closed
產(chǎn)生原因:
1.文件流已經(jīng)關(guān)閉還在繼續(xù)使用