之前的文章介紹了在J2ME環境下GB2312轉換為UTF-8的方法。
/j2me/base/20636.html
在後來繼續對編碼及char類型進行學習,發現一些有趣的問題。
首先Java環境下的char類型變量,實際上就是以unicode方式存儲的。
所以以下方法有效:
輸入unicode編碼的byte數組,即可兩兩拼接成一個char。
而String類型實際上就是在char數組的基礎上衍生出來的。大家可以參考cldc的源代碼。
public static String read_Uni(byte[] Word_unicode) {
StringBuffer stringbuffer = new StringBuffer("");
for (int j = 0; j < Word_unicode.length;) {
int l = Word_unicode[j++];
int h = Word_unicode[j++];
char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));
stringbuffer.append(c);
}
return stringbuffer.toString();
}
J2ME環境下也是如此。
所以在第一次給出的轉換類中,提供的gb2312到utf-8直接轉換的快速方法。現在看來是畫蛇添足了。
根據以上經驗,更新轉換類如下:
public class HGB2312 {
private byte[] map = new byte[15228];
public HGB2312() throws Exception {
InputStream is = getClass().getResourceAsStream("/gb2u.dat");
is.read(map);
is.close();
}
public String gb2utf8(byte[] gb) {
StringBuffer sb = new StringBuffer();
int c, h, l, ind;
for (int i = 0; i < gb.length;) {
if (gb[i] >= 0) {
sb.append((char) gb[i++]);
} else {
h = 256 + gb[i++];
l = 256 + gb[i++];
h = h - 0xA0 - 1;
l = l - 0xA0 - 1;
if (h < 9) {
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
sb.append((char) c);
} else if (h >= 9 && h <= 14) {
sb.append((char) 0);
} else if (h > 14) {
h -= 6;
ind = (h * 94 + l) << 1;
c = (byte2Int(map[ind]) << 8 | byte2Int(map[ind + 1]));
sb.append((char) c);
} else {
sb.append((char) 0);
}
}
}
return sb.toString();
}
private int byte2Int(byte b) {
if (b < 0) {
return 256 + b;
} else {
return b;
}
}
}
這個方法明顯要比第一次快很多了,直接查表,然後拼接成String,不需要轉換成utf-8編碼。