在Java中,String的getBytes()方法是得到一個作業系統預設的編碼格式的位元組數組。這個表示在不同情況下,傳回的東西不一樣!
String.getBytes(String decode)方法會根據指定的decode編碼傳回某字元串在該編碼下的byte數組表示,如:
Java代碼
- byte[] b_gbk = "深".getBytes("GBK");
- byte[] b_utf8 = "深".getBytes("UTF-8");
- byte[] b_iso88591 = "深".getBytes("ISO8859-1");
- byte[] b_unicode = "深".getBytes("unicode");
将分别傳回“深”這個漢字在GBK、UTF-8、ISO8859-1和unicode編碼下的byte數組表示,此時b_gbk的長度為2,b_utf8的長度為3,b_iso88591的長度為1,unicode為4。
而與getBytes相對的,可以通過new String(byte[], decode)的方式來還原這個“深”字時,這個new String(byte[], decode)實際是使用decode指定的編碼來将byte[]解析成字元串。
Java代碼
- String s_gbk = new String(b_gbk,"GBK");
- String s_utf8 = new String(b_utf8,"UTF-8");
- String s_iso88591 = new String(b_iso88591,"ISO8859-1");
- String s_unicode = new String(b_unicode, "unicode");
通過列印s_gbk、s_utf8、s_iso88591和unicode,會發現,s_gbk、s_utf8和unicode都是“深”,而隻有s_iso88591是一個不認識的字元,為什麼使用ISO8859-1編碼再組合之後,無法還原“深”字呢,其實原因很簡單,因為ISO8859-1編碼的編碼表中,根本就沒有包含漢字字元,當然也就無法通過"深".getBytes("ISO8859-1");來得到正确的“深”字在ISO8859-1中的編碼值了,是以再通過new String()來還原就無從談起了。
是以,通過String.getBytes(String decode)方法來得到byte[]時,一定要确定decode的編碼表中确實存在String表示的碼值,這樣得到的byte[]數組才能正确被還原。
有時候,為了讓中文字元适應某些特殊要求(如http header頭要求其内容必須為iso8859-1編碼),可能會通過将中文字元按照位元組方式來編碼的情況,如
String s_iso88591 = new String("深".getBytes("UTF-8"),"ISO8859-1"),
這樣得到的s_iso8859-1字元串實際是三個在 ISO8859-1中的字元,在将這些字元傳遞到目的地後,目的地程式再通過相反的方式String s_utf8 = new String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")來得到正确的中文漢字“深”。這樣就既保證了遵守協定規定、也支援中文。
同樣,在開發會檢查字元長度,以免資料庫字段的長度不夠而報錯,考慮到中英文的差異,肯定不能用String.length()方法判斷,而需采用String.getBytes().length;而本方法将傳回該作業系統預設的編碼格式的位元組數組。如字元串“Hello!你好!”,在一個中文WindowsXP系統下,結果為12,而在英文的UNIX環境下,結果将為9。因為該方法和平台(編碼)相關的。在中文作業系統中,getBytes方法傳回的是一個GBK或者GB2312的中文編碼的位元組數組,其中中文字元,各占兩個位元組,而在英文平台中,一般的預設編碼是"ISO-8859-1",每個字元都隻取一個位元組(而不管是否非拉丁字元)。是以在這種情況下,應該給其傳入字元編碼字元串,即String.getBytes("GBK").length。
- import <a href="http://lib.csdn.net/base/javase" class='replace_word' title="Java SE知識庫" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>.nio.charset.Charset;
- import java.util.Iterator;
- import java.util.Set;
- public class javaCode {
- public static void main(String args[])
- {
- Set<String> charsetNames = Charset.availableCharsets().keySet();
- System.out.println("-----the number of jdk1.67's charset is "+charsetNames.size()+"-----");
- for (Iterator it = charsetNames.iterator(); it.hasNext();)
- {
- String charsetName = (String) it.next();
- System.out.println(charsetName);
- }
- }
- }
執行結果
-----the number of jdk1.67's charset is 160-----
Big5
Big5-HKSCS
EUC-JP
EUC-KR
GB18030
GB2312
GBK
IBM-Thai
IBM00858
IBM01140
IBM01141
IBM01142
IBM01143
IBM01144
IBM01145
IBM01146
IBM01147
IBM01148
IBM01149
IBM037
IBM1026
IBM1047
IBM273
IBM277
IBM278
IBM280
IBM284
IBM285
IBM297
IBM420
IBM424
IBM437
IBM500
IBM775
IBM850
IBM852
IBM855
IBM857
IBM860
IBM861
IBM862
IBM863
IBM864
IBM865
IBM866
IBM868
IBM869
IBM870
IBM871
IBM918
ISO-2022-CN
ISO-2022-JP
ISO-2022-JP-2
ISO-2022-KR
ISO-8859-1
ISO-8859-13
ISO-8859-15
ISO-8859-2
ISO-8859-3
ISO-8859-4
ISO-8859-5
ISO-8859-6
ISO-8859-7
ISO-8859-8
ISO-8859-9
JIS_X0201
JIS_X0212-1990
KOI8-R
KOI8-U
Shift_JIS
TIS-620
US-ASCII
UTF-16
UTF-16BE
UTF-16LE
UTF-32
UTF-32BE
UTF-32LE
UTF-8
windows-1250
windows-1251
windows-1252
windows-1253
windows-1254
windows-1255
windows-1256
windows-1257
windows-1258
windows-31j
x-Big5-Solaris
x-euc-jp-linux
x-EUC-TW
x-eucJP-Open
x-IBM1006
x-IBM1025
x-IBM1046
x-IBM1097
x-IBM1098
x-IBM1112
x-IBM1122
x-IBM1123
x-IBM1124
x-IBM1381
x-IBM1383
x-IBM33722
x-IBM737
x-IBM834
x-IBM856
x-IBM874
x-IBM875
x-IBM921
x-IBM922
x-IBM930
x-IBM933
x-IBM935
x-IBM937
x-IBM939
x-IBM942
x-IBM942C
x-IBM943
x-IBM943C
x-IBM948
x-IBM949
x-IBM949C
x-IBM950
x-IBM964
x-IBM970
x-ISCII91
x-ISO-2022-CN-CNS
x-ISO-2022-CN-GB
x-iso-8859-11
x-JIS0208
x-JISAutoDetect
x-Johab
x-MacArabic
x-MacCentralEurope
x-MacCroatian
x-MacCyrillic
x-MacDingbat
x-MacGreek
x-MacHebrew
x-MacIceland
x-MacRoman
x-MacRomania
x-MacSymbol
x-MacThai
x-MacTurkish
x-MacUkraine
x-MS950-HKSCS
x-mswin-936
x-PCK
x-UTF-16LE-BOM
X-UTF-32BE-BOM
X-UTF-32LE-BOM
x-windows-50220
x-windows-50221
x-windows-874
x-windows-949
x-windows-950
x-windows-iso2022jp