java 中的字符编码转换
参考解答
首先明确一点:java中存储一个字符,都是利用了unicode字符编码, 总是占用两个字节(想想char)
例如:
String s1 = "h"; // 在java中实际存储为 \u0068
中文也同样是两个字节:
String s2 = "中"; // 在java中实际存储为 \u4e2d
但java对外输出(如文件、网络),会采用其它的字符编码,例如ISO-8859-1
、GBK
、UTF-8
等
ISO-8859-1
只占一个字节,只能表示英文字符GBK
可以表示中英文字符,英文字符占一个字节,中文字符占两个字节UTF-8
可以表示中英文(全球语言)字符,英文字符占一个字节,中文字符占三个字节
可以使用getBytes("字符编码")
将java中的 unicode 字符按不同的字符编码转换为字节,下面列出了几种转换结果:
byte[] out;
out = "h".getBytes("ISO-8859-1"); // {0x68}
out = "h".getBytes("GBK"); // {0x68}
out = "中".getBytes("GBK"); // {0xd6, 0xd0}
out = "h".getBytes("UTF-8"); // {0x68}
out = "中".getBytes("UTF-8"); // {0xe4, 0xb8, 0xad}
可以使用new String(byte[], "字符编码")
将字节按某种编码还原成java 的 unicode:
String str;
str = new String(new byte[]{0x68},"ISO-8859-1"); // 还原为\u0068
str = new String(new byte[]{(byte)0xd6, (byte)0xd0},"GBK");// 还原为\u4e2d
str = new String(new byte[]{(byte)0xe4, (byte)0xb8, (byte)0xad},"UTF-8"); // 还原为\u4e2d
思考下面的例子,会怎么样?
String str = new String("中".getBytes("GBK"),"ISO-8859-1");
分析:
- "中".getBytes("GBK") 结果转换为字节数组:{0xd6, 0xd0}
- 再将{0xd6, 0xd0} 按"ISO-8859-1"还原为unicode:\u00d6 \u00d0, 直接打印的效果是 ÖÐ
- 这就是web开发中著名的乱码问题
如何解决呢?再做一次对称的操作即可:
String r = new String("ÖÐ".getBytes("ISO-8859-1"),"GBK"); // 还原成\u4e2
其实就是:
String str = "ÖÐ"; // 上一步的乱码,即\u00d6 \u00d0
byte[] b = str.getBytes("ISO-8859-1"); //{0xd6, 0xd0}
String r = new String(b,"GBK"); // 还原成\u4e2d