Java---IO加強(3)-IO流的操作規律
一般寫關于操作文件的讀取的幾個通用步驟!!!

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
網絡(Socket)
★ 明確是否需要額外功能?
1) 是否需要高效?緩沖區Buffered (字符與字節各兩個)。
2) 是否需要轉換?轉換流 InputStreamReader OutputStreamWriter
3) 是否操作基本數據類型? DataInputStream DataOutputStream
4) 是否操作對象(對象序列化)? ObjectInputStream ObjectOutputStream
5) 需要對多個源合并嗎? SequenceInputStream
6) 需要保證數據的表現形式到目的地嗎? PrintStream 或 PrintWriter
IO流的操作規律之設計方案練習需求1:復制一個文本文件。
1、明確源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、處理的數據是否是純文本的數據?
源:Reader
目的:Writer
3、明確數據所在的設備。
源:file(硬盤)
目的:file(硬盤)
4、明確是否需要額外功能?
BufferedReader bufr = new BufferedReader(new FileReader(“a.txt”));
BufferedWriter bufw = new BufferedWriter(new FileWriter(“b.txt”));
IO流的操作規律之設計方案練習需求2:復制一個圖片文件。
1、明確源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、處理的數據是否是純文本的數據?
源:InputStream
目的:OutputStream
3、明確數據所在的設備。
源:file(硬盤) FileInputStream fin = new FileInputStream(“1.jpg”);
目的:file(硬盤) FileOutputStream fout = new FileOutputStrema(“2.jpg”);
4、明確是否需要額外功能?
BufferedInputStream bufin = new BufferedInputStream( fin );
BufferedOutputStream bufout = new BufferedOutputStream( fout );
IO流的操作規律之設計方案練習需求3:讀取鍵盤錄入,存儲到一個文件中。
1、明確源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、處理的數據是否是純文本的數據?
源:Reader
目的:Writer
3、明確數據所在的設備。
源:鍵盤 InputStream in = System.in;
目的:硬盤 FileWriter fw = new FileWriter(“a.txt”);
4、明確是否需要額外功能?
(必須要將鍵盤錄入的字節轉成字符。
需要將字節–>字符的轉換流。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:讀取一個文本文件,顯示到顯示器上。
1、明確源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、處理的數據是否是純文本的數據?
源:Reader
目的:Writer
3、明確數據所在的設備。
源:硬盤 FileReader fr = new FileReader(“a.txt”);
目的:顯示器 OutputStream out = System.out;
4、明確是否需要額外功能?
(要將字符數據轉換成字節輸出。
輸出轉換流: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寫入到另一個文件中。
1、明確源和目的。
源:InputStream Reader
目的:OutputStream Writer
2、處理的數據是否是純文本的數據?
源:Reader
目的:Writer
3、明確數據所在的設備。
源:硬盤 FileReader fr = new FileReader(“a.txt”);
目的:硬盤 FileOutputStream fout = new FileOutputStream(“b.txt”);
4、明確是否需要額外功能?
(假定輸出時要為字符數據指定編碼表。轉換流中的參數需要字節流,因此用FileOutputStream。
轉換流:OutputStreamWriter,還想需要高效。)
FileReader fr = new FileReader(“a.txt”);
OutputStreamWriter osw = new OutputStreamWriter(fout,”utf-8”);
BufferedReader bufr = new BufferedReader( fr);
BufferedWriter bufw = new BufferedWriter( osw );
常見的編碼表
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碼。
Unicode符號范圍 | UTF-8編碼方式 (十六進制) | (二進制) -------------------------------+---------------------------------- 0000 0000-0000 007F | 0xxxxxxx 0000 0080-0000 07FF | 110xxxxx 10xxxxxx 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1
2
3
4
5
6
7
package unicode; import java.io.IOException; import java.io.UnsupportedEncodingException; /** * * @author 陳浩翔 * * @version 1.0 2016-4-28 */ public class StringEncoding { public static void main(String[] args) throws IOException { //先演示正常的編碼解碼-----編碼表和解碼表必須一致,否則會亂碼。----還有個前提,碼表中必須要有你給的相應字符 //只有gb2312,gbk和utf-8三個碼表中才有中文,因此對我們來講,只有用這3個表編碼,才能處理中文 String str = "湖南城市"; byte buf[] = str.getBytes("utf-8");//編碼---編碼表是utf-8 //printBytes( buf ); String s = new String(buf,"gbk");//解碼---解碼表是gbk System.out.println(s); //※編碼編錯必掛,解碼解錯可以補救! //編碼編錯必掛 /* String str = "湖南城市"; byte buf[] = str.getBytes("iso8859-1");//編碼---編錯碼了,必掛----因為iso8859-1這個碼表中根本就沒有中文,因此編出來的碼肯定是錯的 printBytes( buf ); */ //解碼解錯可以補救!----中文亂碼解決技術 demo(); } private static void demo() throws IOException { //應用場景: 瀏覽器中網頁(中文數據,字節數組的形式buf[]) --io--> server (Tomcat,iso8859-1) //--->Tomcat會把我們的buf[]用iso8859-1解碼成字符串str(其實是用錯碼表的解碼結果),然后把str通過傳參傳遞到我們寫的程序(servlet)中來 //因此,我們程序中拿到的str是亂碼,由此我們需要把 str恢復成真實的中文數據----該過程就叫中文亂碼解決 //1瀏覽器 String str1 = "湖南城院"; byte buf1[] = str1.getBytes();//用系統默認的編碼---GBK或UTF-8 //2Tomcat String str2 = new String(buf1,"iso8859-1");//解錯碼 System.out.println("Tomcat解碼后的數據:"+str2); Tomcat把str2通過傳參傳給MyServlet //3MyServlet---解決亂碼 byte buf2[] = str2.getBytes("iso8859-1");//反查---編碼 String str = new String(buf2);//用系統默認的碼表解碼 System.out.println("MyServlet解決籌碼之后:"+str); } private static void printBytes(byte[] buf) { for(byte b: buf){ System.out.print(b+" "); } System.out.println(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//看看大部分漢字在UTF-8中的占有的字節數
package unicode; import java.io.IOException; import java.io.UnsupportedEncodingException; /** * * @author 陳浩翔 * * @version 1.0 2016-4-28 */ public class UnicodeDemo1 { public static void main(String[] args) throws IOException { String str = "湖南城市"; byte buf[] = str.getBytes("utf-8"); printBytes( buf ); } private static void printBytes(byte[] buf) { for(byte b: buf){ System.out.print(b+" "); } System.out.println(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
輸出結果:
-26 -71 -106 -27 -115 -105 -27 -97 -114 -27 -72 -126
1
2
Java 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。