中文亂碼問題在咱們平常開發中司空見慣,那麼亂碼問題是如何產生的呢?又怎樣去解決亂碼問題呢?本文將結合基本概念和例子展開闡述,但願你們有收穫。html
package whx;
import java.io.UnsupportedEncodingException;
public class TestEncodeAndDecode {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "測試中文亂碼";
byte[] b = str.getBytes("GBK");
System.out.println(new String (b,"UTF-8"));
}
}
複製代碼
用GBK編碼,用utf-8解碼,產生亂碼,運行結果以下:java
要理解亂碼的根源,須要先了解清楚位、字節、字符、字符集等相關概念。mysql
位是計算機存儲數據的最小單位,1或者0就表示1位,如10010010就表示8位的二進制數。程序員
字節是計算機信息技術用於計量存儲容量的一種計量單位,做爲一個單位來處理的一個二進制數字串,是構成信息的一個小單位。sql
1 B = 8 bit (1字節等於8位)
1 KB = 1024 B = 1024 字節
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
複製代碼
字符是指計算機中使用的字母、數字、字和符號,是數據結構中最小的數據存取單位。如a、A、B、b、大、+、*、%等都表示一個字符;數據庫
在 ASCII 編碼中,一個英文字母字符存儲須要1個字節。
在 GB 2312 編碼或 GBK編碼中,一個漢字字符存儲須要2個字節。
在UTF-8編碼中,一個英文字母字符存儲須要1個字節,一個漢字字符儲存須要3到4個字節。
在UTF-16編碼中,一個英文字母字符或一個漢字字符存儲都須要2個字節
在UTF-32編碼中,世界上任何字符的存儲都須要4個字節
複製代碼
字符集是多個字符的集合,字符集種類較多,每一個字符集包含的字符個數不一樣。常見字符集名稱:windows
ASCII字符集
GB2312字符集
Unicode字符集
複製代碼
計算機只認識二進制的1和0,而人類都是有本身的語言的,雙方要能進行信息交流,必需要有從文字到0、1的轉化,以及0、1到文字轉化。bash
編碼: 就是將文本字符轉換成計算機能夠識別的0、1機器碼。session
解碼: 將存儲在計算機中的二進制數解析成文字、字符。數據結構
常見字符集有ASCII、GBK、Unicode等
ASCII字符集:它包括英文字母、阿拉伯數字和西文符號等可顯示字符,以及回車鍵、退格等控制字符。
ASCII 編碼:它是美國製定的字符編碼,用於將英語字符轉化爲二進制,規定了128個字符的編碼。
GBXXXX系列包括GB23十二、GBK、GB18030,適用於漢字處理、漢字通訊等系統之間的信息交換。
GB2312
GBK
GB18030
Unicode是國際組織制定的能夠容納世界上全部文字和符號的字符編碼方案。UNICODE字符集有多種編碼方式,分別是UTF-8,UTF-16和UTF-32。
UTF-8
UTF-16
UTF-32
咱們敲代碼的程序員,接觸最多的就是「hello word」。計算機只認識0和1,它是怎麼展現hello word的呢?
上一小節,咱們已經知道編碼、字符集的知識。咱們能夠用ASCII編碼,把「hello word」翻譯成計算機認識的0、1。有興趣的朋友能夠去查一下 ASCII對照表
計算機存儲的是hello world的0、1二進制碼,先將二進制碼解碼成對應的字符,而後在屏幕上渲染出來,咱們看到的就是hello world了
亂碼產生的緣由主要有兩個,一是文本字符編碼過程與解碼過程使用了不一樣的編碼方式,二是使用了缺乏某種字體庫的字符集引發的亂碼。
例子中,用了utf-8編碼,使用了GBK解碼,結果產生了亂碼。由於在utf-8中,一個漢字用三個字節編碼,而GBK中,每一個漢字用兩個字節表示,因此產生了亂碼。
咱們知道GB2312是不支持繁體字的,因此使用缺乏某種字體庫的字符集編碼,會產生亂碼。
使用支持要展現字體的字符集編碼,而且編解碼使用同一種編碼方式,就能夠解決亂碼問題了。
接下來列舉一下亂碼的經典場景與解決方案
IDE項目中的中文亂碼問題?File->settings->Editor->File Encodings,設置一下編碼方式utf-8
IDE控制檯中文亂碼?嘗試一下這種方式,打開IDE安裝目錄,找到
查看數據庫編碼:
show variables like 'character_set%'
複製代碼
//session 範圍
set character_set_server=utf8;
set character_set_database=utf8;
//global 範圍
set global character_set_database=utf8;
set global character_set_server=utf8;
複製代碼
session、global範圍編碼,重啓mysql可能編碼又變回去了,能夠嘗試另一種方式。在mysql(windows環境)的my.ini配置文件中修改或添加下列內容
[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8
[client]
default-character-set=utf8
複製代碼
寫代碼的時候出現中文亂碼?追蹤定位到編碼解碼的地方,設置用同一種編碼方式。