上次介紹的是檔案的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。

arrow
arrow
    全站熱搜

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