【Java 基础专题】编码与乱码(02)

Posted on

【Java 基础专题】编码与乱码(02)---String的getBytes([encoding])方法测试

[登录] [注册]|

程序人生

【Java 基础专题】编码与乱码(02)---String的getBytes([encoding])方法测试

[ 251 浏览 ][手机版]

返回列表 发布日期: 2010-02-22 23:50 发布者: cobra 1/#

字体大小: t T

上一篇:【Java 基础专题】编码与乱码(01)---编码基础

  1. package example.encoding; 1.
  2. import java.io.UnsupportedEncodingException; 1.
  3. /// /////*
  4. /* The Class GetBytesTest.
  5. /*/
  6. public class GetBytesTest { 1.
  7. /// /////*
  8. /* The main method.
  9. /*
  10. /* @param args the arguments
  11. /*/
  12. public static void main(String args[]) {
  13. String content = "中文";
  14. String defaultEncoding = System.getProperty("file.encoding");
  15. String defaultLnaguage = System.getProperty("user.language");
  16. System.out.println("System default encoding --- " + defaultEncoding);
  17. System.out.println("System default language --- " + defaultLnaguage); 1.
  18. GetBytesTest tester = new GetBytesTest(); 1.
  19. byte[] defaultBytes = tester.getBytesWithDefaultEncoding(content);
  20. tester.printBytes(defaultBytes); 1.
  21. byte[] iso8859Bytes = tester.getBytesWithGivenEncoding(content,
  22. "ISO-8859-1");
  23. tester.printBytes(iso8859Bytes); 1.
  24. byte[] gbkBytes = tester.getBytesWithGivenEncoding(content, "GBK");
  25. tester.printBytes(gbkBytes); 1.
  26. byte[] utfBytes = tester.getBytesWithGivenEncoding(content, "UTF-8");
  27. tester.printBytes(utfBytes); 1.
  28. } 1.
  29. /// /////*
  30. /* Gets the bytes with default encoding.
  31. /*
  32. /* @param content the content
  33. /*
  34. /* @return the bytes with default encoding
  35. /*/
  36. public byte[] getBytesWithDefaultEncoding(String content) {
  37. System.out.println("\nEncode with default encoding\n");
  38. byte[] bytes = content.getBytes();
  39. return bytes;
  40. } 1.
  41. /// /////*
  42. /* Gets the bytes with given encoding.
  43. /*
  44. /* @param content the content
  45. /* @param encoding the encoding
  46. /*
  47. /* @return the bytes with given encoding
  48. /*/
  49. public byte[] getBytesWithGivenEncoding(String content, String encoding) {
  50. System.out.println("\nEncode with given encoding : " + encoding + "\n");
  51. try {
  52. byte[] bytes = content.getBytes(encoding);
  53. return bytes;
  54. } catch (UnsupportedEncodingException e) {
  55. e.printStackTrace();
  56. return null;
  57. }
  58. } 1.
  59. /// /////*
  60. /* Prints the bytes.
  61. /*
  62. /* @param bytes the bytes
  63. /*/
  64. public void printBytes(byte[] bytes) {
  65. for (int i = 0; i < bytes.length; i++) {
  66. System.out.print(" byte[" + i + "] = " + bytes);
  67. System.out
  68. .println(" hex string = " + Integer.toHexString(bytes));
  69. }
  70. } 1.
  71. } 复制代码 【1】在中文平台下,测试结果如下: System default encoding --- GBK System default language --- zh Encode with default encoding byte[0] = -42 hex string = ffffffd6 byte[1] = -48 hex string = ffffffd0 byte[2] = -50 hex string = ffffffce byte[3] = -60 hex string = ffffffc4 Encode with given encoding : ISO-8859-1 byte[0] = 63 hex string = 3f byte[1] = 63 hex string = 3f Encode with given encoding : GBK byte[0] = -42 hex string = ffffffd6 byte[1] = -48 hex string = ffffffd0 byte[2] = -50 hex string = ffffffce byte[3] = -60 hex string = ffffffc4 Encode with given encoding : UTF-8 byte[0] = -28 hex string = ffffffe4 byte[1] = -72 hex string = ffffffb8 byte[2] = -83 hex string = ffffffad byte[3] = -26 hex string = ffffffe6 byte[4] = -106 hex string = ffffff96 byte[5] = -121 hex string = ffffff87 【2】在英文平台下,测试结果如下: System default encoding --- Cp1252 System default language --- en Encode with default encoding byte[0] = 63 hex string = 3f byte[1] = 63 hex string = 3f Encode with given encoding : ISO-8859-1 byte[0] = 63 hex string = 3f byte[1] = 63 hex string = 3f Encode with given encoding : GBK byte[0] = -42 hex string = ffffffd6 byte[1] = -48 hex string = ffffffd0 byte[2] = -50 hex string = ffffffce byte[3] = -60 hex string = ffffffc4 Encode with given encoding : UTF-8 byte[0] = -28 hex string = ffffffe4 byte[1] = -72 hex string = ffffffb8 byte[2] = -83 hex string = ffffffad byte[3] = -26 hex string = ffffffe6 byte[4] = -106 hex string = ffffff96 byte[5] = -121 hex string = ffffff87 【结论】 getBytes()、getBytes(encoding)函数的作用是使用系统默认或者指定的字符集编码方式,将字符串编码成字节数组。 在中文平台下,默认的字符集编码是GBK,此时如果使用getBytes()或者getBytes("GBK"),则按照GBK的编码规则将每个中文字符用2个byte表示。所以我们看到"中文"最终GBK编码结果就是: -42 -48 -50 -60 。-42和-48代表了"中"字,而"-50"和"-60"则代表了"文"字。 在中文平台下,如果指定的字符集编码是UTF-8,那么按照UTF-8对中文的编码规则:每个中文用3个字节表示,那么"中文"这两个字符最终被编码成:-28 -72 -83、-26 -106 -121两组。每3个字节代表一个中文字符。 在中文平台下,如果指定的字符集编码是ISO-8859-1,由于此字符集是单字节编码,所以使用getBytes("ISO-8859-1") 时,每个字符只取一个字节,每个汉字只取到了一半的字符。另外一半的字节丢失了。由于这一半的字符在字符集中找不到对应的字符,所以默认使用编码63代替,也就是?。 在英文平台下,默认的字符集编码是Cp1252(类似于ISO-8859-1),如果使用GBK、UTF-8进行编码,得到的字节数组依然是正确的 (GBK4个字节,UTF-8是6个字节)。因为在JVM内部是以Unicode存储字符串的,使用getBytes(encoding)会让JVM进行一次Unicode到指定编码之间的转换。对于GBK,JVM依然会转换成4个字节,对于UTF-8,JVM依然会转换成6个字节。但是对于ISO- 8859-1,则由于无法转换(2个字节--->1个字节,截取了一半的字节),所以转换后的结果是错误的。 相同的平台下,同一个中文字符,在不同的编码方式下,得到的是完全不同的字节数组。这些字节数组有可能是正确的(只要该字符集支持中文),也可能是完全错误的(该字符集不支持中文)。 记住: 不要轻易地使用或滥用String类的getBytes(encoding)方法,更要尽量避免使用getBytes()方法。因为这个方法是平台依赖的,在平台不可预知的情况下完全可能得到不同的结果。如果一定要进行字节编码,则用户要确保encoding的方法就是当初字符串输入时的 encoding。(文/Paul Lin) 下一篇:【Java 基础专题】编码与乱码(03)----String的toCharArray()方法测试

赞助商广告: 下面是更多相关的免费资源

《Google Android开发入门与实战》源码下载修订后的电子书Java Persistence with Hibernate(英文版)下载《OSGi原理与最佳实践》精选版下载Google Android应用框架原理与程式设计36技Java NIO 入门学习(读写文件)Java NIO 入门学习(通道和缓冲区)Java NIO 入门学习(过门)精简的JAVA计算器代码Groovy 深入探索——Metaclass的存放Java NIO 应用 -- 使用内存映射文件实现进程间通信共享内存在Java中实现和应用Spring 2.5 中文简明教程下载Java制作的快速打开文件夹、程序的小工具《Programming in Lua》中文版PDFKiller Game Programming in JavaJ2ME XHTML浏览器、J2ME WML浏览器、J2ME WAP浏览器(0.50b版)使用Ant实现zip压缩解压功能免费论坛程序JForum的安装说明JavaBean一键生成插件:JavaBeanAssistantThe Definitive Guide to Jython: Python for the Java Platform **TOP

返回列表 赞助商广告:

拼吾爱程序人生 - 统计 - Sitemap 鄂ICP备07500843号

CopyRight © 2007-2010 Pin5i-Programming-Life 本站法律顾问:ITLAW-庄毅雄律师

Powered by Discuz!NT 3.0.0 Processed in 0.09375 second(s) , 6 queries.

希望本站内容对您有点用处,有什么疑问或建议请在后面留言评论
转载请注明作者(RobinChia)和出处 It so life ,请勿用于任何商业用途