字節流不能操作Unicode字符,由於Java采用16位的Unicode字符,即一個字符占16位,所以要使用基於字符的輸入輸出操作。所以創造了字符流,以提供直接的字符輸入輸出的支持。
Reader和Writer。
用於讀取字符流的抽象類。子類必須實現的方法只有 read(char[], int, int) 和 close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
寫入字符流的抽象類。子類必須實現的方法僅有 write(char[], int, int)、flush() 和 close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
InputStreamReader是字節流通向字符流的橋梁:它使用指定的 charset 讀取字節並將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平台默認的字符集。
OutputStreamWriter 是字符流通向字節流的橋梁:可使用指定的 charset 將要寫入流中的字符編碼成字節。它使用的字符集可以由名稱指定或顯式給定,否則將接受平台默認的字符集。
public static void main(String[] args) throws IOException { //創建文件字節輸出流 FileOutputStream fos = new FileOutputStream("D:/itzhai/arthinking.txt"); //把字節輸出流轉換成字符輸出流,並使用了BufferedWriter提供緩沖功能 BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(fos)); bw.write("arthinking"); bw.close(); //創建文件字節輸入流 FileInputStream fis = new FileInputStream("D:/itzhai/arthinking.txt"); //把字節輸入流轉換成字符輸入流,並使用了BufferedReader提供緩沖功能 BufferedReader br = new BufferedReader( new InputStreamReader(fis)); String str = br.readLine(); while(null != str){ System.out.println(str); str = br.readLine(); } br.close(); }
標准的輸出流和標准的輸入流是字節流:
public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String str; while(null != (str = br.readLine())){ System.out.println(str); } }
用來讀取字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩沖區大小都是適當的。要自己指定這些值,可以先在 FileInputStream 上構造一個 InputStreamReader。
FileReader 用於讀取字符流。要讀取原始字節流,請考慮使用 FileInputStream。
用來寫入字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩沖區大小都是可接受的。要自己指定這些值,可以先在 FileOutputStream 上構造一個 OutputStreamWriter。
文件是否可用或是否可以被創建取決於底層平台。特別是某些平台一次只允許一個 FileWriter(或其他文件寫入對象)打開文件進行寫入。在這種情況下,如果所涉及的文件已經打開,則此類中的構造方法將失敗。
FileWriter 用於寫入字符流。要寫入原始字節流,請考慮使用 FileOutputStream。
public static void main(String[] args) throws IOException { String str = "hello world!!!"; //創建字符數組並初始化 char[] buffer = new char[str.length()]; str.getChars(0, str.length(), buffer, 0); //創建FileWriter FileWriter fw = new FileWriter("D:/itzhai/arthinking.txt"); //逐個字符的輸出到文件 for(int i=0; i<buffer.length; i++){ fw.write(buffer[i]); } fw.close(); //創建FileReader BufferedReader br = new BufferedReader( new FileReader("D:/itzhai/arthinking.txt")); //使用BufferedReader提供的逐行讀取函數讀取文件 while(null != (str = br.readLine())){ System.out.println(str); } br.close(); }
此類實現一個可用作字符輸入流的字符緩沖區。
此類實現一個可用作 Writer 的字符緩沖區。緩沖區會隨向流中寫入數據而自動增長。可使用 toCharArray() 和 toString() 獲取數據。
注:在此類上調用 close() 無效,並且在關閉該流后可以調用此類中的各個方法,而不會產生任何 IOException。
public static void main(String[] args) throws IOException { String str = "arthinking"; //創建並初始化字符數組 char[] ch = new char[str.length()]; str.getChars(0, str.length(), ch, 0); //通過字符數組初始化字符數組輸入流 CharArrayReader cr = new CharArrayReader(ch); int c; while(-1 != (c = cr.read())){ System.out.print((char)c); } }
此類的實例既可以支持對隨機訪問文件的讀取也可以支持對其寫入。
隨機訪問文件的行為類似存儲在文件系統中的一個大型 byte 數組。存在指向該隱含數組的光標或索引,稱為文件指針;輸入操作從文件指針開始讀取字節,並隨着對字節的讀取而前移此文件指針。如果隨機訪問文件以讀取/寫入模式創建,則輸出操作也可用;輸出操作從文件指針開始寫入字節,並隨着對字節的寫入而前移此文件指針。寫入隱含數組的當前末尾之后的輸出操作導致該數組擴展。該文件指針可以通過 getFilePointer 方法讀取,並通過 seek 方法設置。
通常,如果此類中的所有讀取例程在讀取所需數量的字節之前已到達文件末尾,則拋出 EOFException(是一種 IOException)。如果由於某些原因無法讀取任何字節,而不是在讀取所需數量的字節之前已到達文件末尾,則拋出 IOException,而不是 EOFException。需要特別指出的是,如果流已被關閉,則可能拋出 IOException。
public static void main(String[] args) throws IOException { //創建隨機訪問文件 RandomAccessFile raf = new RandomAccessFile("D:/itzhai/arthinking.txt", "rw"); //寫入數據 raf.writeInt(1); raf.writeChar('a'); //文件指針復位 raf.seek(0); //輸出數據 System.out.println(raf.readInt() + "" + raf.readChar()); }
它主要用於顯示現代英語和其他西歐語言。它是現今最通用的單字節編碼系統,並等同於國際標准ISO 646。可顯示字符:英文大小寫字符、阿拉伯數字和西文符號。
是四方國家所使用的編碼機,單字節的字符集。
GB2312是中國國家標准的簡體中文字符集。它所收錄的漢字已經覆蓋99.75%的使用頻率,基本滿足了漢字的計算機處理需要。在中國大陸和新加坡獲廣泛使用。
除了完全兼容GB2312之外,還對繁體中文,不常用漢字和特殊符號進行了編碼。
UTF-8便於不同的計算機之間使用網絡傳輸不同語言和編碼的文字,使得雙字節的Unicode能夠在現存的處理單字節的系統上正確傳輸。
UTF-8使用可變長度字節來儲存 Unicode字符,例如ASCII字母繼續使用1字節儲存,重音文字、希臘字母或西里爾字母等使用2字節來儲存,而常用的漢字就要使用3字節。輔助平面字符則使用4字節。
一種通用字符集,每個字符都用2個字節來表示,對於英文字符采用前面補0的方法實現等長兼容。