更新時間:2020-11-19 17:30:06 來源:動力節(jié)點 瀏覽1170次
我們在學習字符流(FileReader、FileWriter)的時候,其中說如果需要指定編碼和緩沖區(qū)大小時,可以在字節(jié)流的基礎上,構造一個InputStreamReader或者OutputStreamWriter,這又是什么意思呢?這其中就涉及到了IO轉換流的相關知識。
為了方便我們的理解可以先來看一下轉換流原理圖:
一、OutputStreamWriter類
查閱OutputStreamWriter的API介紹,OutputStreamWriter 是字符流通向字節(jié)流的橋梁:可使用指定的字符編碼表,將要寫入流中的字符編碼成字節(jié)。它的作用的就是,將字符串按照指定的編碼表轉成字節(jié),在使用字節(jié)流將這些字節(jié)寫出去。
public static void writeCN() throws Exception {
//創(chuàng)建與文件關聯的字節(jié)輸出流對象
FileOutputStream fos = new FileOutputStream("c:\\cn8.txt");
//創(chuàng)建可以把字符轉成字節(jié)的轉換流對象,并指定編碼
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
//調用轉換流,把文字寫出去,其實是寫到轉換流的緩沖區(qū)中
osw.write("你好");//寫入緩沖區(qū)。
osw.close();
}
OutputStreamWriter流對象,它到底如何把字符轉成字節(jié)輸出的呢?
其實在OutputStreamWriter流中維護自己的緩沖區(qū),當我們調用OutputStreamWriter對象的write方法時,會拿著字符到指定的碼表中進行查詢,把查到的字符編碼值轉成字節(jié)數存放到OutputStreamWriter緩沖區(qū)中。然后再調用刷新功能,或者關閉流,或者緩沖區(qū)存滿后會把緩沖區(qū)中的字節(jié)數據使用字節(jié)流寫到指定的文件中。
java.io.OutputStreamWriter extends Writer
OutputStreamWriter: 是字符流通向字節(jié)流的橋梁:可使用指定的 charset 將要寫入流中的字符編碼成字節(jié)。(編碼:把能看懂的變成看不懂)
繼續(xù)自父類的共性成員方法:
- void write(int c) 寫入單個字符。
- void write(char[] cbuf)寫入字符數組。
- abstract void write(char[] cbuf, int off, int len)寫入字符數組的某一部分,off數組的開始索引,len寫的字符個數。
- void write(String str)寫入字符串。
- void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個數。
- void flush()刷新該流的緩沖。
- void close() 關閉此流,但要先刷新它。
構造方法:
OutputStreamWriter(OutputStream out)創(chuàng)建使用默認字符編碼的OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName) 創(chuàng)建使用指定字符集的 OutputStreamWriter。
參數:
OutputStream out:字節(jié)輸出流,可以用來寫轉換之后的字節(jié)到文件中
String charsetName:指定的編碼表名稱,不區(qū)分大小寫,可以是utf-8/UTF-8,gbk/GBK,...不指定默認使用UTF-8
使用步驟:
1.創(chuàng)建OutputStreamWriter對象,構造方法中傳遞字節(jié)輸出流和指定的編碼表名稱
2.使用OutputStreamWriter對象中的方法write,把字符轉換為字節(jié)存儲緩沖區(qū)中(編碼)
3.使用OutputStreamWriter對象中的方法flush,把內存緩沖區(qū)中的字節(jié)刷新到文件中(使用字節(jié)流寫字節(jié)的過程)
4.釋放資源
二、InputStreamReader類
查閱InputStreamReader的API介紹,InputStreamReader 是字節(jié)流通向字符流的橋梁:它使用指定的字符編碼表讀取字節(jié)并將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺默認的字符集。
java.io.InputStreamReader extends Reader
InputStreamReader:是字節(jié)流通向字符流的橋梁:它使用指定的 charset 讀取字節(jié)并將其解碼為字符。(解碼:把看不懂的變成能看懂的)
繼承自父類的共性成員方法:
int read() 讀取單個字符并返回。
int read(char[] cbuf)一次讀取多個字符,將字符讀入數組。
void close() 關閉該流并釋放與之關聯的所有資源。
構造方法:
InputStreamReader(InputStream in) 創(chuàng)建一個使用默認字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 創(chuàng)建使用指定字符集的 InputStreamReader。
參數:
InputStream in:字節(jié)輸入流,用來讀取文件中保存的字節(jié)
String charsetName:指定的編碼表名稱,不區(qū)分大小寫,可以是utf-8/UTF-8,gbk/GBK,...不指定默認使用UTF-8
使用步驟:
1.創(chuàng)建InputStreamReader對象,構造方法中傳遞字節(jié)輸入流和指定的編碼表名稱
2.使用InputStreamReader對象中的方法read讀取文件
3.釋放資源
注意事項:
構造方法中指定的編碼表名稱要和文件的編碼相同,否則會發(fā)生亂碼
代碼演示
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//演示字節(jié)轉字符流的轉換流
readCN();
}
public static void readCN() throws IOException{
//創(chuàng)建讀取文件的字節(jié)流對象
InputStream in = new FileInputStream("c:\\cn8.txt");
//創(chuàng)建轉換流對象
//InputStreamReader isr = new InputStreamReader(in);
//這樣創(chuàng)建對象,會用本地默認碼表讀取,將會發(fā)生錯誤解碼的錯誤
InputStreamReader isr = new InputStreamReader(in,"utf-8");
//使用轉換流去讀字節(jié)流中的字節(jié)
int ch = 0;
while((ch = isr.read())!=-1){
System.out.println((char)ch);
}
//關閉流
isr.close();
}
}
在讀取指定的編碼的文件時,一定要指定編碼格式,否則就會發(fā)生解碼錯誤,而發(fā)生亂碼現象。
通俗一點來說,磁盤中的存儲的數據都是“看不懂”的,也就是以字節(jié)形式存儲的。而內存中存儲的數據都是“看得懂”的,也就是以字符形式存儲的。把“看得懂”的數據轉換成"看不懂"的數據,即把字符流編碼成字節(jié)流。好了,IO轉換流的知識就講到這里,感興趣的小伙伴可以在消化完本文之后,觀看本站的Java教程,繼續(xù)深入學習Java IO流的知識。