字符集是非英语国家人最头疼的事情,尤其是样样有国标的中国。所以本朝的码农比洋大人程序员学各种技能都要多会一个技能点——应付编码问题。
NIO我们同样需要面对编码解码问题。
1 * 六、字符集:CharSet 2 * 编码:字符串 -> 字节数组 3 * 解码:字节数组 -> 字符串
有哪些编码呢?
1 @Test 2 public void test5(){ 3 SortedMap<String, Charset> availableCharsets = Charset.availableCharsets(); 4 for(Entry<String, Charset> entry:availableCharsets.entrySet()){ 5 System.out.println(String.format("%s: %s", entry.getKey(), entry.getValue())); 6 } 7 }
输出了NIO支持的各种编码:
1Big5: Big5 2Big5-HKSCS: Big5-HKSCS 3CESU-8: CESU-8 4EUC-JP: EUC-JP 5EUC-KR: EUC-KR 6GB18030: GB18030 7GB2312: GB2312 8GBK: GBK 9IBM-Thai: IBM-Thai 10IBM00858: IBM00858 11IBM01140: IBM01140 12IBM01141: IBM01141 13IBM01142: IBM01142 14IBM01143: IBM01143 15IBM01144: IBM01144 16IBM01145: IBM01145 17IBM01146: IBM01146 18IBM01147: IBM01147 19IBM01148: IBM01148 20IBM01149: IBM01149 21IBM037: IBM037 22IBM1026: IBM1026 23IBM1047: IBM1047 24IBM273: IBM273 25IBM277: IBM277 26IBM278: IBM278 27IBM280: IBM280 28IBM284: IBM284 29IBM285: IBM285 30IBM290: IBM290 31IBM297: IBM297 32IBM420: IBM420 33IBM424: IBM424 34IBM437: IBM437 35IBM500: IBM500 36IBM775: IBM775 37IBM850: IBM850 38IBM852: IBM852 39IBM855: IBM855 40IBM857: IBM857 41IBM860: IBM860 42IBM861: IBM861 43IBM862: IBM862 44IBM863: IBM863 45IBM864: IBM864 46IBM865: IBM865 47IBM866: IBM866 48IBM868: IBM868 49IBM869: IBM869 50IBM870: IBM870 51IBM871: IBM871 52IBM918: IBM918 53ISO-2022-CN: ISO-2022-CN 54ISO-2022-JP: ISO-2022-JP 55ISO-2022-JP-2: ISO-2022-JP-2 56ISO-2022-KR: ISO-2022-KR 57ISO-8859-1: ISO-8859-1 58ISO-8859-13: ISO-8859-13 59ISO-8859-15: ISO-8859-15 60ISO-8859-2: ISO-8859-2 61ISO-8859-3: ISO-8859-3 62ISO-8859-4: ISO-8859-4 63ISO-8859-5: ISO-8859-5 64ISO-8859-6: ISO-8859-6 65ISO-8859-7: ISO-8859-7 66ISO-8859-8: ISO-8859-8 67ISO-8859-9: ISO-8859-9 68JIS_X0201: JIS_X0201 69JIS_X0212-1990: JIS_X0212-1990 70KOI8-R: KOI8-R 71KOI8-U: KOI8-U 72Shift_JIS: Shift_JIS 73TIS-620: TIS-620 74US-ASCII: US-ASCII 75UTF-16: UTF-16 76UTF-16BE: UTF-16BE 77UTF-16LE: UTF-16LE 78UTF-32: UTF-32 79UTF-32BE: UTF-32BE 80UTF-32LE: UTF-32LE 81UTF-8: UTF-8 82windows-1250: windows-1250 83windows-1251: windows-1251 84windows-1252: windows-1252 85windows-1253: windows-1253 86windows-1254: windows-1254 87windows-1255: windows-1255 88windows-1256: windows-1256 89windows-1257: windows-1257 90windows-1258: windows-1258 91windows-31j: windows-31j 92x-Big5-HKSCS-2001: x-Big5-HKSCS-2001 93x-Big5-Solaris: x-Big5-Solaris 94x-euc-jp-linux: x-euc-jp-linux 95x-EUC-TW: x-EUC-TW 96x-eucJP-Open: x-eucJP-Open 97x-IBM1006: x-IBM1006 98x-IBM1025: x-IBM1025 99x-IBM1046: x-IBM1046 100x-IBM1097: x-IBM1097 101x-IBM1098: x-IBM1098 102x-IBM1112: x-IBM1112 103x-IBM1122: x-IBM1122 104x-IBM1123: x-IBM1123 105x-IBM1124: x-IBM1124 106x-IBM1166: x-IBM1166 107x-IBM1364: x-IBM1364 108x-IBM1381: x-IBM1381 109x-IBM1383: x-IBM1383 110x-IBM300: x-IBM300 111x-IBM33722: x-IBM33722 112x-IBM737: x-IBM737 113x-IBM833: x-IBM833 114x-IBM834: x-IBM834 115x-IBM856: x-IBM856 116x-IBM874: x-IBM874 117x-IBM875: x-IBM875 118x-IBM921: x-IBM921 119x-IBM922: x-IBM922 120x-IBM930: x-IBM930 121x-IBM933: x-IBM933 122x-IBM935: x-IBM935 123x-IBM937: x-IBM937 124x-IBM939: x-IBM939 125x-IBM942: x-IBM942 126x-IBM942C: x-IBM942C 127x-IBM943: x-IBM943 128x-IBM943C: x-IBM943C 129x-IBM948: x-IBM948 130x-IBM949: x-IBM949 131x-IBM949C: x-IBM949C 132x-IBM950: x-IBM950 133x-IBM964: x-IBM964 134x-IBM970: x-IBM970 135x-ISCII91: x-ISCII91 136x-ISO-2022-CN-CNS: x-ISO-2022-CN-CNS 137x-ISO-2022-CN-GB: x-ISO-2022-CN-GB 138x-iso-8859-11: x-iso-8859-11 139x-JIS0208: x-JIS0208 140x-JISAutoDetect: x-JISAutoDetect 141x-Johab: x-Johab 142x-MacArabic: x-MacArabic 143x-MacCentralEurope: x-MacCentralEurope 144x-MacCroatian: x-MacCroatian 145x-MacCyrillic: x-MacCyrillic 146x-MacDingbat: x-MacDingbat 147x-MacGreek: x-MacGreek 148x-MacHebrew: x-MacHebrew 149x-MacIceland: x-MacIceland 150x-MacRoman: x-MacRoman 151x-MacRomania: x-MacRomania 152x-MacSymbol: x-MacSymbol 153x-MacThai: x-MacThai 154x-MacTurkish: x-MacTurkish 155x-MacUkraine: x-MacUkraine 156x-MS932_0213: x-MS932_0213 157x-MS950-HKSCS: x-MS950-HKSCS 158x-MS950-HKSCS-XP: x-MS950-HKSCS-XP 159x-mswin-936: x-mswin-936 160x-PCK: x-PCK 161x-SJIS_0213: x-SJIS_0213 162x-UTF-16LE-BOM: x-UTF-16LE-BOM 163X-UTF-32BE-BOM: X-UTF-32BE-BOM 164X-UTF-32LE-BOM: X-UTF-32LE-BOM 165x-windows-50220: x-windows-50220 166x-windows-50221: x-windows-50221 167x-windows-874: x-windows-874 168x-windows-949: x-windows-949 169x-windows-950: x-windows-950 170x-windows-iso2022jp: x-windows-iso2022jp
如何编解码
方法是用Charset.forName(String)构造一个编码器或解码器,利用编码器和解码器来对CharBuffer编码,对ByteBuffer解码。
但是请注意,在对CharBuffer编码之前、对ByteBuffer解码之前,请记得对CharBuffer、ByteBuffer进行flip()切换到读模式,否则什么都没有。
如果编码和解码的格式不同,则会出现乱码。
1 @Test 2 public void test6() throws CharacterCodingException{ 3 Charset charset1 = Charset.forName("GBK"); 4 //获取编码器 5 CharsetEncoder encoder = charset1.newEncoder(); 6 7 //获取解码器 8 CharsetDecoder decoder = charset1.newDecoder(); 9 10 CharBuffer charBuffer = CharBuffer.allocate(1024); 11 charBuffer.put("happyBKs的博客"); 12 13 14 //编码 15 charBuffer.flip();//因为编码要读取charBuffer,所以要先切到度模式 16 ByteBuffer byteBuffer=encoder.encode(charBuffer); 17 18 //byteBuffer.limit()为14,英文字符一个1 byte,中文字符一个2 byte 19 for(int i_byteBuffer=0;i_byteBuffer<byteBuffer.limit();i_byteBuffer++){ 20 System.out.println(byteBuffer.get()); 21 } 22 23 //解码 24 byteBuffer.flip();//因为解码要读取byteBuffer,所以要先切到度模式,不然下面一行什么也不输出 25 CharBuffer charBufferDecoded=decoder.decode(byteBuffer); 26 System.out.println(charBufferDecoded.toString()); 27 28 System.out.println("---------------------------------------------------"); 29 30 Charset utf8Chatset = Charset.forName("UTF-8"); 31 byteBuffer.flip();//byteBuffer刚才读过了,现在需要从头再读一遍,需要先调用flip() 32 CharBuffer charBufferDecodedByUTF8=utf8Chatset.decode(byteBuffer); 33 System.out.println(charBufferDecodedByUTF8.toString()); 34 35 36 System.out.println("---------------------------------------------------"); 37 Charset gbkChatset = Charset.forName("GBK"); 38 byteBuffer.flip();//byteBuffer刚才读过了,现在需要从头再读一遍,需要先调用flip() 39 CharBuffer charBufferDecodedByGBK=gbkChatset.decode(byteBuffer); 40 System.out.println(charBufferDecodedByGBK.toString()); 41 42 }
输出结果:
1104 297 3112 4112 5121 666 775 8115 9-75 10-60 11-78 12-87 13-65 14-51 15happyBKs的博客 16--------------------------------------------------- 17happyBKs�IJ��� 18--------------------------------------------------- 19happyBKs的博客
所以我们在以后对文件系统进行NIO编程时,如果出现问题,原因可以这样归类:
如果结果为空 ,那么问题时在编码或解码之前没有将缓冲区切换到读模式。
如果结果又乱码,那么是编码器或者解码器出现差错;也有可能是只输出了一部分在缓冲区,多字节字符被截断造成的。