java的IO流之字符編碼

1.字符編碼的發展歷程

階段1:
計算機只認識數字,我們在計算機裏一切數據都是以數字來表示,因爲英文符號有限,
所以規定使用的字節的最高位是0.每一個字節都是以0~127之間的數字來表示,比如A對應65,a對應97.
這就是美國標準信息交換碼-ASCII.

階段2:
隨着計算機在全球的普及,很多國家和地區都把自己的字符引入了計算機,比如漢字.
此時發現一個字節能表示數字範圍太小,不能包含所有的中文漢字,那麼就規定使用兩個字節來表示一個漢字.
規定:原有的ASCII字符的編碼保持不變,仍然使用一個字節表示,爲了區別一箇中文字符與兩個ASCII碼字符,
中文字符的每個字節最高位規定爲1(中文的二進制是負數).這個規範就是GB2312編碼,
後來在GB2312的基礎上增加了更多的中文字符,比如漢字,也就出現了GBK.

階段3:
新的問題,在中國是認識漢字的,但是如果把漢字傳遞給其他國家,該國家的碼錶中沒有收錄漢字,其實就顯示另一個符號或者亂碼.
爲了解決各個國家因爲本地化字符編碼帶來的影響,咱們就把全世界所有的符號統一進行編碼-Unicode編碼.
此時某一個字符在全世界任何地方都是固定的,比如'哥',在任何地方都是以十六進制的54E5來表示.
Unicode的編碼字符都佔有2個字節大小.
--------------------------------------------------------------------------------------------------------------
常見的字符集:
ASCII: 佔一個字節,只能包含128個符號. 不能表示漢字
ISO-8859-1:(latin-1):佔一個字節,收錄西歐語言,.不能表示漢字.
ANSI:佔兩個字節,在簡體中文的操作系統中 ANSI 就指的是 GB2312.
GB2312/GBK/GB18030:佔兩個字節,支持中文.
UTF-8:是一種針對Unicode的可變長度字符編碼,又稱萬國碼,是Unicode的實現方式之一。
編碼中的第一個字節仍與ASCII兼容,這使得原來處理ASCII字符的軟件無須或只須做少部份修改,即可繼續使用。
因此,它逐漸成爲電子郵件、網頁及其他存儲或傳送文字的應用中,優先採用的編碼。互聯網工程工作小組(IETF)要求所有互聯網協議都必須支持UTF-8編碼。


UTF-8 BOM:是MS搞出來的編碼,默認佔3個字節,不要使用這個.
--------------------------------------------------------------------------------------------------------------
存儲字母,數字和漢字:
存儲字母和數字無論是什麼字符集都佔1個字節.
存儲漢字:   GBK家族佔兩個字節,UTF-8家族佔3個字節.
--------------------------------------------------------------------------------------------------------------

不能使用單字節的字符集(ASCII/ISO-8859-1)來存儲中文.

2.字符的編碼和解碼操作

  編碼:  把字符串轉換爲byte數組.
  解碼:  把byte數組轉換爲字符串.
一定要保證編碼和解碼的字符相同,否則亂碼.

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class IODemo3 {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "楊哥";
		//編碼String---->byte[]
		byte[] bytes = str.getBytes();//我這裏默認是UTF-8
		System.out.println(Arrays.toString(bytes));//[-26, -99, -88, -27, -109, -91]
		
		//解碼byte[]--->String
		String ret = new String(bytes);////我這裏默認是UTF-8
		System.out.println(ret);//楊哥
		System.out.println("================================");
		
		String str2 = "楊哥哥";
		//編碼String---->byte[]
		byte[] bytes2 = str.getBytes("GBK");//我也可以自己指定編碼
		System.out.println(Arrays.toString(bytes2));//[-47, -18, -72, -25]
				
		//解碼byte[]--->String
		String ret2 = new String(bytes2);//我這裏默認是UTF-8,
		System.out.println(ret2);//這裏出現亂碼���,因爲我前面指定了編碼爲GBK
		//所以解碼也應該用GBK
		String ret3 =new String(bytes2, "GBK");
		System.out.println(ret3);//楊哥
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章