字符流:
1. Writer 寫入字符流的抽象類。子類必須實現的方法僅有 write(char[],int,int)、flush()和close()。但是,多數子類將重寫此處定義的一些方法,以提高更高的效率和其它功能
與OutputStream一樣,對文件的操作使用FileWriter類完成。
2. Reader用於讀取字符流的抽象類。子類必須實現的方法只有read(char[],int,int)和close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和其它的功能
使用FileReader類對文件進行操作
在上一小節中,我們使用InputStream的實例化對象in進行in.read(bytes)操作時,有可能文件的大小比bytes要大,一箇中文字符佔兩個字節,而一個英文字符佔一個字節,這是就有可能形成每次讀取到分界處時(比如第一次讀取只讀取了某個漢字的第一個字節,下一次讀取才會讀取該漢字的第二個字節)編碼錯亂。
這時就引入了字符流的概念。
package com.coding.iostudy;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class CharStreamDemo {
public static void main(String[] args) {
// write();
read();
}
public static void write() {
File file = new File("H:/javaCode/folder/b.txt");
try {
Writer out = new FileWriter(file);
String info = "扣丁學堂,讓編程更簡單!";
out.write(info);
out.write("\r\n");
out.close();
} catch(IOException e) {
e.printStackTrace();
}
}
public static void read() {
File file = new File("H:/javaCode/folder/b.txt");
try {
Reader in = new FileReader(file);
char[] cs = new char[2];
int len = -1;
StringBuffer sb = new StringBuffer();
while((len = in.read(cs)) != -1) {
System.out.println(len);
sb.append(new String(cs,0,len));
}
in.close();
System.out.println(sb);
} catch(IOException e) {
e.printStackTrace();
}
}
}
總結:如果操作的是文本類型的文件,建議使用字符流;如果是非文本類型的文件(音頻,圖像,視頻等),建議使用字節流
***********************
一個重要的地方:我們在進行單步調試時,發現在執行in.close()方法時內容纔會寫到文件中,因爲在執行out.write(info)時會先輸出到緩存中,在執行out.close()方法時會默認調用out.flush()方法刷新緩存,將緩存的內容輸出到文件中,當然我們也可以自己顯式調用out.flush()去刷新緩存。而字節流中默認條件下沒有緩存,直接寫入到文件中。
緩存可以提升讀寫效率。我們可以在字節流中加緩存
***********************
在所有的流操作中,字節流是最基礎的。任何基於字節的操作都是正確的,無論是文本文件還是二進制文件,只要不打印出來顯示。如果確認流裏面只有可打印的字符,包括英文和各種國家的文字,可以考慮字符流。由於編碼不同,一個字符可能佔用多個字節,比如GBK的漢字就佔用2個字節,UTF-8的漢字佔用3個字節。所以字符流是根據指定的編碼,將1個或多個字節轉換爲java裏面的unicode字符,然後進行操作。
字符操作一般使用Writer和Reader等,字節操作一般使用InputStream和OutputStream以及各種包裝類。比如BufferedInputStream和BufferedOutputStream等。