1.由於字節流操作中文不是很方便,所以Java 提供了轉換流。
字符流 = 字節流 + 編碼表
編碼表:
ASCII表:美國標準信息交換碼,用一個字節的7位可以表示
ISO8859-1:拉丁碼錶。歐洲碼錶,用一個字節的8位可以表示。
GB2312:中國的中文編碼表
GBK:中國的中文編碼表升級,融合了更多的中文字符。
GB8030:GBK的取代版本
BIG-5:通行於臺灣、香港地區的一個繁體字編碼方案,俗稱“大五碼”
Unicode:國際標準碼,融合了更多文字。所有文字都用兩個字節來表示,Java語言就是用的Unicode
UTF-8:最多用三個字節來表示一個字符,能用一個表示就用一個,不行就兩個,實在不行就三個
2.編碼 、 解碼
String(byte[] bytes, String charsetName) :通過使用指定的 charset 解碼指定的 byte 數組,構造一個新的 String。
byte[] getBytes(String charsetName) :使用指定的字符集將此 String 編碼爲 byte 序列
編碼:把看得懂的變成看不懂的
解碼:把看不懂的變成看得懂的
編碼、解碼使用的編碼表只有是一樣的,才能正確解碼出來結果。
3.轉換流:把字節流轉換爲字符流
OutputStreamWriter、InputStreamReader
字符流 = 字節流 + 編碼表
(1)OutputStreamWriter:
子類:FileWriter(實際我們經常用的是其子類)
構造方法:
OutputStreamWriter(OutputStream out) :根據默認字符編碼把字節流數據轉換爲字符流。
OutputStreamWriter(OutputStream out, String charsetName) :根據指定字符集編碼把字節流數據轉換爲字符流。
//創建對象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"),"GBK") ; //指定GBK編碼
//寫入數據
osw.write("中國") ;
//釋放資源
osw.close() ;
字符流的五種寫入方法:
void write(char[] cbuf) :寫入字符數組。
abstract void write(char[] cbuf, int off, int len) :寫入字符數組的某一部分。
void write(int c) :寫入單個字符。
void write(String str) :寫入字符串。
void write(String str, int off, int len) :寫入字符串的某一部分。
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fos.txt")) ;
// void write(int c) :寫入單個字符。
osw.write("A");
osw.write(97);
//void write(char[] cbuf) :寫入字符數組。
char[] c = {'<','b','c','d','>'} ;
osw.write(c);
//abstract void write(char[] cbuf, int off, int len) :寫入字符數組的某一部分。
osw.write(c,1,3);
// void write(String str) :寫入字符串。
osw.write("12345");
//void write(String str, int off, int len) :寫入字符串的某一部分
osw.write("12345", 1, 3);
//osw.flush();
osw.close();
面試題:close()和flush()的區別?
A:close()關閉流對象,但是先刷新一下緩衝區。關閉之後,流對象不可以繼續使用。
B:flush()僅僅刷新緩衝區,流對象可以繼續使用。
(2)InputStreamReader :
子類:FileReader(實際我們經常用的是其子類)
構造方法:
InputStreamReader(InputStream in) :根據默認字符編碼把字節流數據讀取爲字符流。
InputStreamReader(InputStream in, String charsetName) :根據指定字符集編碼把字節流數據讀取爲字符流。
//創建對象
InputStreamReader isr= new InputStreamReader (new FileInputStream("isr.txt"),"GBK") ; //指定GBK編碼
//讀取數據
int ch = 0 ;
while((ch = isr.read()) != -1 ){
System.out.print((char) ch) ;
}
//釋放資源
isr.close() ;
字符流的兩種讀取方法:
int read() :讀取單個字符
int read(char[] cbuf) : 將字符讀入數組
//創建對象
InputStreamReader isr = new InputStreamReader(new FileInputStream("fis.txt")) ;
// //int read() :讀取單個字符
// int ch = 0 ;
// while((ch = isr.read()) != -1){
// System.out.print((char)ch);
// }
//int read(char[] cbuf) : 將字符讀入數組
char[] chs = new char[1024] ;
int len = 0 ;
while((len = isr.read(chs)) != -1){
System.out.print(new String(chs,0,len));
}
//釋放資源
isr.close();
4.字符轉換流複製文件
//創建對象
InputStreamReader isr = new InputStreamReader(new FileInputStream("fis.txt")) ;
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("fis2.txt")) ;
//讀取數據
char[] chs = new char[1024] ;
int len = 0 ;
while((len = isr.read(chs)) != -1){
//寫入數據
osw.write(new String(chs,0,len));
}
//釋放資源
osw.close();
isr.close();
5.FileReader和FileWriter
由於我們常見的操作都是使用默認編碼,所以不指定編碼。
而轉換流的名字有點長,所以java提供了其子類供我們使用。
其中關係如下:
OutputStreamWriter = FileOutputStream + 編碼表(GBK)
FileWriter = OutputStreamWriter +編碼表(GBK)
InputStreamReader = FileInputStream + 編碼表(GBK)
FileReader = InputStreamReader + 編碼表(GBK)
實際應用中我們基本都是用FileReader和FileWriter而不是其父類。其用法和父類一樣。
如下使用FileReader和FileWriter來複制文件
//封裝資源
FileReader fr = new FileReader("fis.txt") ;
FileWriter fw = new FileWriter("fis2.txt") ;
//讀取數據
char[] chs = new char[1024] ;
int len = 0 ;
while( (len = fr.read(chs)) != -1 ){
//寫入數據
fw.write(new String( chs , 0 , len ));
}
//釋放資源
fr.close();
fw.close();
6.緩衝流:字符流爲了高效率讀寫,提供了對應的字符緩衝流
(1)BufferedWriter:字符緩衝輸出流
構造方法:
BufferedWriter(Writer out) :創建一個使用默認大小輸出緩衝區的緩衝字符輸出流。
BufferedWriter(Writer out, int sz) :創建一個使用給定大小輸出緩衝區的新緩衝字符輸出流。
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
bw.write("中國你好");
bw.close();
(2)BufferedReader:字符緩衝輸入流
構造方法摘要
BufferedReader(Reader in) :創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。
BufferedReader(Reader in, int sz) :創建一個使用指定大小輸入緩衝區的緩衝字符輸入流。
//創建對象
BufferedReader br = new BufferedReader(new FileReader("fis.txt")) ;
//讀取數據
char[] chs = new char[1024] ;
int len = 0 ;
while((len = br.read(chs)) != -1){
System.out.print(new String(chs, 0 , len));
}
//釋放資源
chs.clone();
(3)字符緩衝流的特殊方法:
BufferedWriter:
public void nextLine() :根據系統來決定輸入換行符
BufferedReader:
public void readLine():一次讀取一行數據,包含該行內容的字符串但是不包含任何終止符,如果已達文件末尾,則返回null。
因此,以下代碼纔是我們最常用的代碼:
//寫入方法
public void write() throws IOException {
//封裝資源
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
//寫入數據
for (int i = 0; i < 10; i++) {
bw.write("你好Java-" + i);
bw.newLine();
bw.flush();
}
//釋放資源
bw.close();
}
//讀取方法
public void read() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
String line = null ;
while((line = br.readLine()) != null ){
System.out.println(line);
}
br.close();
}
//複製文件
//封裝資源
BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt")) ;
//讀取數據
String line = null ;
while((line = br.readLine()) != null){
bw.write(line) ;
bw.newLine();
bw.flush() ;
}
//釋放資源
bw.close() ;
br.close() ;