第10組 Alpha衝刺 (3/6)(組長)
字元編碼
計算機中儲存的資訊都是用二進位制數表示的,而我們在螢幕上看到的數字、英文、標點符號,漢字等字元是二進位制數轉換之後的結果,按照某種規則,將字元儲存到計算機中,稱為編碼,反之,將儲存在計算機中的二進位制數按照某種規則解析顯示出來,稱為解碼。比如說,按照A規則儲存,同樣按照A規則解析,那麼就能顯示正確的文字符號。反之,按照A規則儲存,再按照B規則解析,就會導致亂碼現象。
編碼:字元(能看懂)--> 位元組(看不懂)
解碼:位元組(看不懂)--> 字元(能看懂)
字符集:也叫編碼表,是一個系統支援的所有字元的集合,包括各國家文字、標點符號、圖形符號、數字等。
計算機要準確的儲存和識別各種字符集符號,需要進行字元編碼,一套字符集必然至少有一套字元編碼。長劍字符集有ASCII字符集、GBK字符集、Unicode字符集等。
常見的字符集有:ASCII字符集、GBK字符集、Unicode字符集。
編碼引出的問題
在IDEA中,使用FileReader,讀取專案中的文字檔案,由於IDEA的設定,都是預設的UTF-8編碼,所有沒有任何問題。但是,當讀取Windows系統中建立的文字檔案時,由於Windows系統的預設GBK編碼,就會出現亂碼。
package day10; import java.io.FileReader; import java.io.IOException; public class Demo02 { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("C:\\a\\GBK編碼.txt"); int len = 0; while((len = fr.read())!=-1){ System.out.print((char)len); } fr.close(); } }
InputStreamWriter
java.io.OutputStreamWriter extends Writer
OutputStreamWriter:是字元流桐鄉位元組流的喬遼;可使用指定的charset將要寫入流中的字元編碼成位元組。
繼承自父類的共性成員方法:
- void write(int c)寫入單個字元。
- void write(char[] cbuf)寫入字元陣列。
- abstract void write(char[] cbuf,int off,int len)寫入字元陣列的某一部分,off陣列的開始索引,len寫的字元個數。
- void write(String str)寫入字元
- void write(String str,int off,int len)寫入字串的某一部分,off字串的開始索引,len寫的字元個數。
- void flush()重新整理該流的緩衝。
- void close()關閉此流,但要先重新整理它。
構造方法:
OutputStreamWriter(OutputStream out) 建立使用預設字元編碼的OutputStreamWriter。
OutputStreamWriter(OutputStream out,String charsetName) 建立使用指定字符集的OutputStreamWriter.
引數:
OutputStream out:位元組輸出流,可以用來寫轉換之後的位元組到檔案中
String charsetName:指定的編碼表名稱,不區分大小寫,可以是UTF-8/UTF-8,GBK/GBK,....不指定預設使用UTF-8
使用步驟:
- 建立OutputStreamWriter物件,構造方法中傳遞位元組輸出流和指定的編碼表名稱。
- 使用OutputStreamWriter物件中的方法write,把字元轉換為位元組儲存緩衝區中(編碼)
- 使用OutputStreamWriter物件中的方法flush,把記憶體緩衝區中的位元組重新整理到檔案中(使用位元組流寫位元組的過程)
- 釋放資源。
package day10;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException {
write_gbk();
write_utf_8();
}
private static void write_gbk() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\a\\gbk.txt"), "gbk");
osw.write("你好");
osw.flush();
osw.close();
}
private static void write_utf_8() throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\a\\utf-8.txt"), "utf-8");
osw.write("你好");
osw.flush();
osw.close();
}
}
InputStreamReader
java.io.InputStreamReader extends Reader
InputStreamReader:是位元組流通向字元流的橋樑,它使用指定的charset讀取位元組並將其解碼為字元。
繼承自父類的共性成員方法:
int read() 讀取單個字元並返回。
int read(char[] cbuf) 一次讀取多個字元,將字元讀入陣列。
void close() 關閉該流並釋放與之關聯的所有資源。
構造方法:
InputStreamReader(InputStream in) 建立一個使用預設字符集的 InputStreamReader。
InputStreamReader(InputStream in,String charsetName) 建立使用指定字符集的InputStreamReader。
引數:
InputStream in:位元組輸入流,用來讀取檔案中儲存的位元組
String charsetName:指定的編碼表名稱,不區分大小寫,可以是utf-8/utf-8,gbk/utf-8,....不指定預設使用utf-8。
使用步驟:
- 建立InputStreamReader物件,構造方法中傳遞位元組輸入流和指定的編碼表名稱。
- 使用InputStreamReader物件中的方法read讀取檔案。
- 釋放資源。
注意事項:
構造方法中指定的編碼表名稱要和檔案的編碼相同,否則會發生亂碼。
package day10;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo03 {
public static void main(String[] args) throws IOException {
read_utf_8();
read_gbk();
}
private static void read_gbk() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\a\\gbk.txt"),"gbk");
int len = 0;
while((len = isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
private static void read_utf_8() throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\a\\utf-8.txt"),"utf-8");
int len = 0;
while((len = isr.read())!=-1){
System.out.println((char)len);
}
isr.close();
}
}
練習:轉換檔案編碼
需求:將gbk編碼的文字檔案,轉換為utf-8編碼的文字檔案。
分析:
- 讀取一個gbk編碼的檔案
- 建立一個utf-8編碼的檔案,儲存編碼轉換之後的檔案。
- 使用read方法讀取檔案內容,將其儲存到編碼之後的檔案中。
package day10;
import java.io.*;
public class lianxi {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\a\\GBK編碼.txt"),"gbk");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("C:\\a\\UTF-8編碼.txt"),"utf-8");
int len = 0;
while ((len = isr.read())!=-1){
osw.write(len);
}
osw.close();
isr.close();
}
}