一般寫關于操作檔案的讀取的幾個通用步驟!!!
1、明确源和目的。
源:InputStream Reader 一定是被讀取的。
目的:OutputStream Writer 一定是被寫入的。
2、處理的資料是否是純文字的資料?
是:使用字元流。Reader Writer
否:使用位元組流。 InputStream OutputStream
到這裡,兩個明确确定完,就可以确定出要使用哪個體系。接下來,就應該明确具體這個體系要使用哪個具體的對象。(看頂層)
3、明确資料所在的裝置。
到這裡,具體使用哪個對象就可以明确了。(用底層)
4、明确是否需要額外功能?
另外:如果資料有規律,并且源和目的都是file,需要随機通路時,可以使用RandomAccessFile工具類。
明确資料所在的裝置:
源裝置:
鍵盤(System.in)
硬碟(FileXXX)FileReader FileInputStream
記憶體(數組)ByteArrayInputStream CharArrayReader StringReader
網絡(Socket)
目的裝置:
顯示器(控制台System.out)
硬碟(FileXXX)FileWriter FileOutputStream
記憶體(數組)ByteArrayOutputStream CharArrayWriter StringWriter
明确是否需要額外功能?
1) 是否需要高效?緩沖區Buffered (字元與位元組各兩個)。
2) 是否需要轉換?轉換流 InputStreamReader OutputStreamWriter
3) 是否操作基本資料類型? DataInputStream DataOutputStream
4) 是否操作對象(對象序列化)? ObjectInputStream ObjectOutputStream
5) 需要對多個源合并嗎? SequenceInputStream
6) 需要保證資料的表現形式到目的地嗎? PrintStream 或 PrintWriter
IO流的操作規律之設計方案練習需求1:複制一個文本檔案。
源:InputStream Reader
目的:OutputStream Writer
源:Reader
目的:Writer
源:file(硬碟)
目的:file(硬碟)
BufferedReader bufr = new BufferedReader(new FileReader(“a.txt”));
BufferedWriter bufw = new BufferedWriter(new FileWriter(“b.txt”));
IO流的操作規律之設計方案練習需求2:複制一個圖檔檔案。
源:InputStream
目的:OutputStream
源:file(硬碟) FileInputStream fin = new FileInputStream(“1.jpg”);
目的:file(硬碟) FileOutputStream fout = new FileOutputStrema(“2.jpg”);
BufferedInputStream bufin = new BufferedInputStream( fin );
BufferedOutputStream bufout = new BufferedOutputStream( fout );
IO流的操作規律之設計方案練習需求3:讀取鍵盤錄入,存儲到一個檔案中。
源:鍵盤 InputStream in = System.in;
目的:硬碟 FileWriter fw = new FileWriter(“a.txt”);
(必須要将鍵盤錄入的位元組轉成字元。
需要将位元組–>字元的轉換流。InputStreamReader
還想需要高效。)
InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fw = new FileWriter(“a.txt”);
BufferedReader bufr = new BufferedReader( isr);
BufferedWriter bufw = new BufferedWriter( fw );
IO流的操作規律之設計方案練習需求4:讀取一個文本檔案,顯示到顯示器上。
源:硬碟 FileReader fr = new FileReader(“a.txt”);
目的:顯示器 OutputStream out = System.out;
(要将字元資料轉換成位元組輸出。
輸出轉換流:OutputStreamWriter
FileReader fr = new FileReader(“a.txt”);
OutputStreamWriter osw = new OutputStreamWriter(System.out);
BufferedReader bufr = new BufferedReader( fr);
BufferedWriter bufw = new BufferedWriter( osw );
IO流的操作規律之設計方案練習需求5:讀取一個文本檔案,将文本按照指定的編碼表UTF-8寫入到另一個檔案中。
源:硬碟 FileReader fr = new FileReader(“a.txt”);
目的:硬碟 FileOutputStream fout = new FileOutputStream(“b.txt”);
(假定輸出時要為字元資料指定編碼表。轉換流中的參數需要位元組流,是以用FileOutputStream。
轉換流:OutputStreamWriter,還想需要高效。)
OutputStreamWriter osw = new OutputStreamWriter(fout,”utf-8”);
常見的編碼表
ASCII:美國标準資訊交換碼。
用一個位元組的7位可以表示。
ISO8859-1:拉丁碼表。歐洲碼表
用一個位元組的8位表示。
GB2312:中國的中文編碼表。
GBK:中國的中文編碼表更新,融合了更多的中文文字元号。
Unicode:國際标準碼,融合了多種文字。
所有文字都用兩個位元組來表示,Java語言使用的就是unicode
UTF-8:一種變長的unicode碼的實作方式,由1~4個位元組表示。
轉換流的編碼應用
可以将字元以指定編碼格式存儲。
可以對文本資料指定編碼格式來解讀。
指定編碼表的動作由構造函數完成。
字元編碼
編碼:字元串位元組數組
解碼:位元組數組字元串
Unicode和UTF-8的關系
Unicode
世界上存在着多種編碼方式,同一個二進制數字可以被解釋成不同的符号。是以,要想打開一個文本檔案,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。為什麼電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。
可以想象,如果有一種編碼,将世界上所有的符号都納入其中。每一個符号都給予一個獨一無二的編碼,那麼亂碼問題就會消失。這就是Unicode,就像它的名字都表示的,這是一種所有符号的編碼。
Unicode隻是一個符号集,它隻規定了符号的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。
UTF-8
UTF-8是在網際網路上使用最廣的一種unicode的實作方式。其他實作方式還包括UTF-16和UTF-32,不過在網際網路上基本不用。UTF-8是Unicode的實作方式之一。
UTF-8的編碼格式
UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個位元組表示一個符号,根據不同的符号而變化位元組長度。
UTF-8的編碼規則很簡單,隻有二條:
1)對于單位元組的符号,位元組的第一位設為0,後面7位為這個符号的unicode碼。是以對于英語字母,UTF-8編碼和ASCII碼是相同的。
2)對于n位元組的符号(n>1),第一個位元組的前n位都設為1,第n+1位設為0,後面位元組的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符号的unicode碼。
//看看大部分漢字在UTF-8中的占有的位元組數
輸出結果: