基礎知識
位元組和字元
位元組(byte):一個八位的存儲單元,取值範圍一定是0~255;
字元(character):就是一個語言上的符号,"中"字就是一個字元。
字元所占的大小由其編碼方式解決,比如"中"在UTF-8中占3個位元組(0xE4A8AD),而在GBK中,則占兩個位元組(0xD6D0)。
字元集和編碼
字元集:字元的集合,像Unicode字元集,目标就是收納了這個世界上所有語言的文字、符号等;
字元編碼:注意,字元集隻是規定了有哪些字元,而最終決定采用哪些字元,每一個字元用多個位元組表示等問題,
則是由編碼來決定的。像Unicode字元集的編碼方式有很多,
諸如UTF-8、UFT-16、UTF-32等。字元集和字元編碼是分開的概念,
但有時候稱呼上會有些模糊,我們經常籠統地稱這些Unicode字元集的編碼為Unicode編碼。
内碼:作業系統内部的字元編碼。像早期的DOS采用的是ASCII,而現在的作業系統大把采用Unicode編碼。
編碼簡史
先了解一下編碼的曆史,才能知道為什麼要編碼。
計算機對多語言的支援,大緻為分以下三個階段:
階段一:ASCII時代。計算機是DOS時代的計算内碼是ASCII碼,ASCII的表示範圍就是0到127那幾個符号,
這意味着,DOS時代的計算機隻能顯示英文,而無法支援其他語言。
由于英文系國家開創了并繼續主導了計算機的世界,他們自然而然地認為全世界的文字用8個位元組表示足矣。
階段二:ANSI時代。由于上述原因,像我們這些非英文系的國家的為了顯示自家的文字,
不得不一開始就得面對字元編碼的問題,不同國家不同地區都建立了自己的編碼标準。
像中國大陸是GB2312及後來的GBK,台灣是BIG5,日本是JIS。
ASCII字元集,以及這些由此派生并相容的字元集稱為ANSI字元集。
階段三:Unicode時代。為了和諧而出現,相較于以上兩個階段,這個時代稱為國際化時代,
适應了跨平台、跨語言之間交換資訊的需求。
package edu.fjut.charset;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
/*在計算機世界裡,任何的文字都是以指定的編碼方式存在的,在JAVA程式開發中,
*最常見的編碼有一下幾種:ISO8859-1、GBK/GB2312、Unicode、UTF
*ISO8859-1:此編碼屬于單位元組編碼,最多隻能表示0-255的字元範圍,主要用于英文
*GBK/GB2312:中文的國标編碼、專門用來表示漢字,是雙位元組編碼.GB2312隻能表示簡體
*unicode:java中就是使用此編碼方式,也是最标準的一種編碼,是使用16進制表示的編碼.
* 但此編碼不相容ISO8859-1編碼
*UTF:由于Unicode不支援ISO8859-1編碼,而且容易占用更多的空間,而且對于英文字母也
* 需要使用兩個位元組編碼,這樣使用Unicode不便于傳輸和存儲,是以産生了UTF編碼,
* UTF編碼相容了ISO8859-1編碼,可以用來表示所有的語言字元.
* UTF是 Unicode Translation Format,即把Unicode轉做某種格式的意思。
*/
public class CharsetDemo {
//亂碼産生的根本原因是:字元編碼不統一造成的
public static void main(String[] args) throws Exception{
//因為現在的本機環境是中文環境,是以是使用GBK編碼
System.out.println("系統預設編碼:"+System.getProperty("file.encoding"));//GBK
File file=new File("d:"+File.separator+"javase"+File.separator+"code.txt");
OutputStream out=new FileOutputStream(file);//執行個體化輸出流
byte []b="中國,你好".getBytes("ISO8859-1");//轉碼操作,可以指定要的字元編碼
out.write(b);//儲存,打開檔案後,凡是中文的全部變成?????,因為編碼不一緻
//改成支援中文的編碼就行了
out.close();//關閉
}
}