Java I/o操作(三)
以下一小段(至分隔線之前)引自Think in Java 第四版第十章,作為複習
"10.1 輸入和輸出
可將Java庫的IO類分割為輸入與輸出兩個部分,這一點在用Web瀏覽器閱讀聯機Java類文檔時便可知道。通過繼承,從InputStream(輸入資料流)衍生的所有類都擁有名為read()的基本方法,用於讀取單個位元組或者位元組數組。類似地,從OutputStream衍生的所有類都擁有基本方法write(),用於寫入單個位元組或者位元組數組。然而,我們通常不會用到這些方法;它們之所以存在,是因為更複雜的類可以利用它們,以便提供一個更有用的介面。因此,我們很少用單個類建立自己的系統對象。一般情況下,我們都是將多個對象重疊在一起,提供自己期望的功能。我們之所以感到Java的流庫(Stream Library)異常複雜,正是由於為了建立單獨一個結果流,卻需要建立多個對象的緣故。
很有必要按照功能對類進行分類。庫的設計者首先決定與輸入有關的所有類都從InputStream繼承,而與輸出有關的所有類都從OutputStream繼承."
-----------------------------------------------分隔------------------------------------------
Java的IO操作的複雜性正在於建立某一個類必須關聯到其他的很多類,即一個流和一個流首尾相接,形成了一個類似管道的連結,這種模式是“裝飾模式”的一個應用,英文名叫做Decorator.
例如:FileInputStream->BufferdInputStream->DataInputStream;
DataOutputStream->BuffedOutputStream->FileOutputStream;
-----------------------------------------------------------------------------------------------
Java.io.charset.*;
常用的字元集類別:
1.ASCII 是American Standard Code Information Interchange的所寫,是美國資訊交換標準代碼,每個字元一個位元組。常用0~127(十進位),這部分以0為第一位,其餘部分表示特殊字元,為了區別和前面部分,用1開頭。比較通用。
2.GB2312常用中文字編碼,每個字元兩個位元組
3.GBK,完全相容GB2312,並對繁體字和其他不常用字以及特殊符號進行編碼;
字元的編碼格式:
Unicode :為Java採用,每個字元表示為兩個位元組。
UTF-8:一種更加靈活的編碼方式,根據字元的位元的大小來確定用多少個位元組來表示該字元。
-------------------------------------------------------------------------------------------------
對字元流進行操作的Reader和Writer
Java統一使用Unicode對字元進行編碼,每個字元佔用兩個位元組,16位
InputStreamReader和OutputStreamWriter
InputStreamReade,從一個已經存在的InputStream物件建構
充當位元組流轉換為字元流的橋樑,可以在構造時指定解碼規則(charset)
OutputStreamWriter,從一個已經存在的 OutputStream物件建構。
充當字元流轉換為位元組流的橋樑,可以在構造時指定編碼規則(charset)
另引入一個概念:
將字元流轉換為位元組流成為編碼,將位元組流轉換為字元流稱為解碼。
BufferedReader和BufferedWriter
提供帶緩衝的讀寫,提高效率。分別從一個已經存在的Reader和Writer 構造。
------------------------------------------
注意:文字不能正確顯示的問題一定是解碼和編碼規則不匹配。不同碼之間的轉換一般無法復原,比如採用兩個位元組的GB2312轉換為採用一個位元組的ASCII碼會造成資料丟失。但是可以統一轉換成位元組碼之後再進行相應字元流轉換。
------------------------------------------
代碼:
建立test.txt檔案,並對其進行漢字錄入。Import java.nio.charset.*;的意義在於可以解釋 GB2312。
import java.io.*;
import java.nio.charset.*;
public class UnicodeTest
{
public static void main(String[] args) throws Exception
{
FileOutputStream fops=new FileOutputStream("test.txt");
OutputStreamWriter opsw=new OutputStreamWriter(fops,"GB2312");
BufferedWriter bw=new BufferedWriter(opsw);
InputStreamReader ipsr=new InputStreamReader(System.in,"GB2312");
BufferedReader br=new BufferedReader(ipsr);
String[] str=new String[10];
int i=0;
while(i<10)
{
str[i]=br.readLine();
i++;
if(i==10)
System.out.println("Enough now");
}
i=0;
while(i<10)
{
bw.write(str[i],0,str[i].length());
bw.flush();
bw.newLine();
System.out.println("Write line "+i+" completely");
i++;
}
}
}