国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java 關于中文亂碼問題的解決方案與經驗 (1)

2019-11-18 14:18:36
字體:
來源:轉載
供稿:網友

  一、字節和unicode

java內核是unicode的,就連class文件也是,但是很多媒體,包括文件/流的保存方式是使用字節流的。因此Java要對這些字節流經行轉化。char是unicode的,而byte是字節。Java中byte/char互轉的函數在sun.io的包中間有。其中ByteToCharConverter類是中調度,可以用來告訴你,你用的convertor。其中兩個很常用的靜態函數是:



public static ByteToCharConverter getDefault();
public static ByteToCharConverter getConverter(String encoding);


假如你不指定converter,則系統會自動使用當前的encoding,gb平臺上用gbk,en平臺上用8859_1。


byte ??〉char:
"你"的gb碼是:0xc4e3 ,unicode是0x4f60
String encoding = "gb2312";
byte b[] = {(byte)′u00c4′,(byte)′u00e3′};
ByteToCharConverter converter = ByteToCharConverter.getConverter(encoding);
char c[] = converter.convertAll(b);
for (int i = 0; i < c.length; i++) {
System.out.PRintln(Integer.toHexString(c[i]));
}
結果是什么?0x4f60
假如encoding ="8859_1",結果又是什么?0x00c4,0x00e3


假如代碼改為:

byte b[] = {(byte)′u00c4′,(byte)′u00e3′};
ByteToCharConverter converter = ByteToCharConverter. getDefault();
char c[] = converter.convertAll(b);
for (int i = 0; i < c.length; i++) {
System.out.println(Integer.toHexString(c[i]));
}




結果將又是什么?

這就要根據平臺的編碼而定。


char ??〉byte:
String encoding = "gb2312";
char c[] = {′u4f60′};
CharToByteConverter converter = CharToByteConverter.getConverter(encoding);
byte b[] = converter.convertAll(c);
for (int i = 0; i < b.length; i++) {
System.out.println(Integer.toHexString(b[i]));
}
結果是什么?0x00c4,0x00e3
假如encoding ="8859_1",結果又是什么?0x3f
假如代碼改為
String encoding = "gb2312";
char c[] = {′u4f60′};
CharToByteConverter converter = CharToByteConverter.getDefault();
byte b[] = converter.convertAll(c);
for (int i = 0; i < b.length; i++) {
System.out.println(Integer.toHexString(b[i]));
}




結果將又是什么?還是根據平臺的編碼而定。

很多中文問題就是從這兩個最簡單的類派生出來的。而卻有很多類不直接支持把encoding輸入,這給我們帶來諸多不便。很多程序難得用encoding了,直接用default的encoding,這就給我們移植帶來了很多困難。

二、utf-8

utf-8是和unicode一一對應的,其實現很簡單:


7位的unicode: 0 _ _ _ _ _ _ _
11位的unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _
16位的unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
21位的unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _




大多數情況是只使用到16位以下的unicode:


"你"的gb碼是:0xc4e3 ,unicode是0x4f60
0xc4e3的二進制:
1100 ,0100 ,1110 ,0011




由于只有兩位我們按照兩位的編碼來排,但是我們發現這行不通,因為第7位不是0因此,返回"?"


0x4f60的二進制:
0100 ,1111 ,0110 ,0000
我們用utf-8補齊,變成:
1110 ,0100 ,1011 ,1101 ,1010 ,0000
e4--bd-- a0
于是返回:0xe4,0xbd,0xa0。




三、string和byte[]

string其實核心是char[],然而要把byte轉化成string,必須經過編碼。string.length()其實就是char數組的長度,假如使用不同的編碼,很可能會錯分,造成散字和亂碼。例如:


String encoding = “”;
byte [] b={(byte)′u00c4′,(byte)′u00e3′};
String str=new String(b,encoding);




假如encoding=8859_1,會有兩個字,但是encoding=gb2312只有一個字這個問題在處理分頁是經常發生。

四、Reader,Writer / InputStream,OutputStream

Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char讀/寫InputStream/OutputStream。例如:


文件test.txt只有一個"你"字,0xc4,0xe3
String encoding = "gb2312";
InputStreamReader reader = new InputStreamReader(new FileInputStream(
"text.txt"), encoding);
char c[] = new char[10];
int length = reader.read(c);
for (int i = 0; i < length; i++) {
System.out.println(c[i]);
}




結果是什么?是"你"。假如encoding ="8859_1",結果是什么?"??"兩個字符,表示不熟悉。反過來的例子自己做。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海林市| 竹溪县| 炎陵县| 宜春市| 策勒县| 芜湖市| 罗甸县| 尚志市| 晋宁县| 阜宁县| 霍林郭勒市| 灵璧县| 绍兴县| 思茅市| 西林县| 资中县| 汕尾市| 商水县| 闻喜县| 平陆县| 南乐县| 滦平县| 黎平县| 鹿泉市| 利川市| 乌什县| 行唐县| 二连浩特市| 蒙自县| 九龙坡区| 深水埗区| 兰坪| 海淀区| 仙居县| 当阳市| 哈密市| 莱州市| 色达县| 永安市| 墨江| 安西县|