上次介紹的是檔案的Big5轉UTF-8,但把字串轉成資料流再轉換編碼,似乎比檔案轉碼來得複雜一點:

public static String getEncodingString(String str, String srcEnc, String targetEnc) {
ByteArrayInputStream bais = null;
BufferedReader br = null;
try {
bais = new ByteArrayInputStream(str.getBytes(srcEnc));
br = new BufferedReader(new InputStreamReader(bais, srcEnc));
ByteArrayOutputStream boas = new ByteArrayOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(boas, targetEnc);
osw.write(br.readLine());
osw.flush();
byte[] ba = boas.toByteArray();
for (int i=0; i<ba.length; i++) {
System.out.printf("%02X ", ba[i]);
}
return boas.toString(targetEnc);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

上面的method傳進的參數是要轉碼的字串、字串原編碼、要轉碼之編碼。比檔案轉碼多出的地方是:

  • 在字串轉成ByteArrayInputStream時,getBytes要指定來源編碼。
  • 轉碼到ByteArrayOutputStream,toString也要指定目的編碼。

以下以"一"作為測試之用,"一"在Unicode編碼是\u4E00,在Big5編碼是A440。Java字串預設編碼是Unicode,切勿String str = "一"; 這樣宣告,它必定為Unicode編碼,除非javac -encoding Big5來編譯。以下是測試用例:

byte baChOneBig5[] = new byte[2];
baChOneBig5[0] = (byte)0xA4; // Big5編碼A440 ==> 0xA4, 0x40
baChOneBig5[1] = (byte)0x40;
String char1 = new String(baChOneBig5, "BIG5"); // 由byte[]轉成String就可以是Big5字串
System.out.println("Big5: " + char1);
System.out.println(" >> " + getEncodingString(char1, "Big5", "Unicode"));
System.out.println(" >> " + getEncodingString(char1, "Big5", "UTF-8"));

得到的結果如下:

Big5: 一
FE FF 4E 00 >> 一 Unicode編碼\u4E00, 但不知前面的FEFF是怎麼來的。
E4 B8 80 >> 一 UTF-8在"一"的編碼。

其實在String char1 = new String(baChOneBig5, "BIG5");的時候,若Integer.toHexString(char1.charAt(0)).toUpperCase()會得到什麼編碼?其實不是A440,而是4E00。在存成Java String時,還是Unicode。

文章標籤
全站熱搜
創作者介紹
創作者 Jemmy 的頭像
Jemmy

Jemmy Walker

Jemmy 發表在 痞客邦 留言(0) 人氣(3,741)