String的getBytes()方法是得到一個字串的字節數組,這是眾所周知的。但非凡要注重的是,本方法將返回該操作系統默認的編碼格式的字節數組。假如你在使用這個方法時不考慮到這一點,你會發現在一個平臺上運行.
良好的系統,放到另外一臺機器后會產生意想不到的問題。比如下面的程序,class TestCharset { public static void main(String[] args) { new TestCharset().execute(); } PRivate void execute() { String s = "Hello!你好!"; byte[] bytes = s.getBytes(); System.out.println("bytes lenght is:" + bytes.length); }}
在一個中文WindowsXP系統下,運行時,結果為:bytes lenght is:12
但是假如放到了一個英文的UNIX環境下運行:
$ java TestCharset
bytes lenght is:9
假如你的程序依靠于該結果,將在后續操作中引起問題。為什么在一個系統中結果為12,而在另外一個卻變成了9了呢?上面已經提到了,該方法是和平臺(編碼)相關的。在中文操作系統中,getBytes方法返回的是一個GBK或者GB2312的中文編碼的字節數組,其中中文字符,各占兩個字節。而在英文平臺中,一般的默認編碼是“ISO-8859-1”,每個字符都只取一個字節(而不管是否非拉丁字符)。
Java中的編碼支持
Java是支持多國編碼的,在Java中,字符都是以Unicode進行存儲的,比如,“你”字的Unicode編碼是“4f60”,我們可以通過下面的實驗代碼來驗證:
class TestCharset { public static void main(String[] args) { char c = '你'; int i = c; System.out.println(c); System.out.println(i); }}
不管你在任何平臺上執行,都會有相同的輸出:
----------------- output ------------------
你
20320
20320就是Unicode “4f60”的整數值。其實,你可以反編譯上面的類,可以發現在生成的.class文件中字符“你”(或者其它任何中文字串)本身就是以Unicode編碼進行存儲的:
char c = '/u4F60'; ... ...
進入討論組討論。
使用String.getBytes(String charset)方法
所以,為了避免這種問題,我建議大家都在編碼中使用String.getBytes(String charset)方法。下面我們將從字串分別提取ISO-8859-1和GBK兩種編碼格式的字節數組,看看會有什么結果:
class TestCharset { public static void main(String[] args) { new TestCharset().execute(); } private void execute() { String s = "Hello!你好!"; byte[] bytesISO8859 =null; byte[] bytesGBK = null; try { bytesISO8859 = s.getBytes("iso-8859-1"); bytesGBK = s.getBytes("GBK"); } catch (java.io.UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println("-------------- /n 8859 bytes:"); System.out.println("bytes is: " + arrayToString(bytesISO8859)); System.out.println("hex format is:" + encodeHex(bytesISO8859)); System.out.println(); System.out.println("-------------- /n GBK bytes:"); System.out.println("bytes is: " + arrayToString(bytesGBK)); System.out.println("hex format is:" + encodeHex(bytesGBK)); } public static final String encodeHex (byte[] bytes) { StringBuffer buff = new StringBuffer(bytes.length * 2); String b; for (int i=0; i<bytes.length ; i++) { b = Integer.toHexString(bytes[i]); // byte是兩個字節的,而上面的Integer.toHexString會把字節擴展為4個字節 buff.append(b.length() > 2 ? b.substring(6,8) : b); buff.append(" "); } return buff.toString(); } public static final String arrayToString (byte[] bytes) { StringBuffer buff = new StringBuffer(); for (int i=0; i<bytes.length ; i++) { buff.append(bytes[i] + " "); } return buff.toString(); }}
新聞熱點
疑難解答