【转】java 与 iso-8859-1 编码

  • Post author:
  • Post category:java



今天又研究了一下字符编码。写了些测试代码,算是比较了解了。

主要是研究 iso-8859-1

建议先看这篇:《第二篇:JAVA字符编码系列二:Unicode,ISO-8859-1,GBK,UTF-8编码及…》

http://my.oschina.net/whp/blog/36846

然后再看看 iso-8859-1 的定义。

http://baike.baidu.com/view/2613676.htm



这一句话非常关键:

因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。

在工作中,从 web 提交的数据,到了 web 容器后,变成了 iso-8859-1 的字符串。

可以认为,被执行了如下代码:

byte[] buf_gbk = s.getBytes(“gbk”);

String sIso88591 = new String(buf_gbk, “iso-8859-1”);

所以,我们获取数据时需要执行:

byte[] buf_iso88591 = sIso88591.getBytes(“iso-8859-1”);

String sGbk = new String(buf_iso88591, “gbk”);

将编码转回 gbk。



我们本应该用


gbk


的编码来读取数据并解码成字符串,但结果却采用了ISO-8859-1的编码,导致生成一个错误的字符串。要恢复,就要先把字符串恢复成原始字节数组,然后通过正确的编码


gbk


再次解码成字 符串(即把以


gbk


编码的数据转成unicode的字符串)。注意,

jvm中的字符串永远都是unicode编码的



但编码转换并不是负负得正那么简单,这里我们之所以可以正确地转换回来,是因为 ISO8859-1 是单字节编码,所以每个字节被按照原样转换为String ,也就是说,虽然这是一个错误的转换,但编码没有改变,所以我们仍然有机会把编码转换回来!

看完这两篇后,写了段测试代码:

Java代码

收藏代码



  1. package


    com.fsti.enc;




  2. public




    class


    EncUtil {




  3. public




    static


    String getHex(


    byte


    b)


  4. {

  5. String hex = Integer.toHexString(b &

    0xff


    );



  6. if


    (hex.length()==


    1


    )


  7. {

  8. hex =

    “0”


    + hex;


  9. }


  10. return


    hex;


  11. }



  12. public




    static




    void


    showBytes(


    byte


    [] buffer)


  13. {


  14. for


    (


    int


    i=


    0


    ; i<buffer.length; i++)


  15. {

  16. System.out.print( getHex(buffer[i]) +

    ” ”


    );


  17. }

  18. System.out.println();


  19. }



  20. public




    static




    void


    showChar(String s)


  21. {


  22. for


    (


    int


    i=


    0


    ; i<s.length(); i++)


  23. {

  24. System.out.print( getHex((

    byte


    )(s.charAt(i))) +


    ” ”


    );


  25. }

  26. System.out.println();


  27. }


  28. }

Java代码

收藏代码



  1. package


    com.fsti.enc;





  2. /**



  3. * http://baike.baidu.com/view/2613676.htm



  4. * @author zch



  5. * @date Apr 20, 2012



  6. *



  7. */





  8. public




    class


    Test_Iso8859_1


    extends


    EncUtil{



  9. public




    static


    String s =



  10. “http://baike.baidu.com/view/2613676.htm\r\n”


    +



  11. “  ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,”


    +



  12. “0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。”


    +



  13. “ISO-8859-1收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语”


    +



  14. “对应的文字符号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中。\r\n”


    +



  15. “  因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何”


    +



  16. “编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是”


    +



  17. “个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。ASCII编码是一个7位的容器,”


    +



  18. “ISO-8859-1编码是一个8位的容器。\r\n”


    +



  19. “  Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。”


    ;




  20. public




    static




    void


    testChar(


    char


    c)


    throws


    Exception


  21. {


  22. //char c = ‘中’;




  23. System.out.println( c );

  24. System.out.println( (

    int


    )c );


  25. System.out.println( Integer.toHexString(c) );


  26. if


    (c>


    255


    )


  27. {


  28. byte


    low = (


    byte


    )(c /


    256


    );



  29. byte


    hight = (


    byte


    )(c %


    256


    );


  30. System.out.println( getHex(low) );

  31. System.out.println( getHex(hight) );

  32. }

  33. }



  34. public




    static




    void


    testString()


    throws


    Exception


  35. {


  36. for


    (


    int


    i=


    0


    ; i<s.length(); i++)


  37. {

  38. testChar(s.charAt(i));

  39. }

  40. }




  41. public




    static




    void


    testString_02()


    throws


    Exception


  42. {


  43. StringBuffer sb =

    new


    StringBuffer();



  44. for


    (


    int


    i=


    0


    ; i<s.length(); i++)


  45. {


  46. char


    c = s.charAt(i);



  47. if


    (c>


    255


    )


  48. {


  49. char


    hight = (


    char


    )(c /


    256


    );



  50. char


    low = (


    char


    )(c %


    256


    );


  51. sb.append(hight);

  52. sb.append(low);

  53. }


  54. else




  55. {

  56. sb.append(c);

  57. }

  58. }

  59. String sIso88591 = sb.toString();

  60. System.out.println(sIso88591);



  61. byte


    [] buf = sIso88591.getBytes(


    “iso-8859-1”


    );


  62. showBytes(buf);

  63. String sUtf_8 =

    new


    String(buf,


    “gbk”


    );


  64. System.out.println(sUtf_8);

  65. }



  66. public




    static




    void


    testString_03()


    throws


    Exception


  67. {

  68. System.out.println(

    “s:”


    + s);




  69. byte


    [] buf_gbk = s.getBytes(


    “gbk”


    );


  70. System.out.println(

    “buf_gbk:”


    );


  71. showBytes(buf_gbk);


  72. StringBuffer sb =

    new


    StringBuffer();



  73. for


    (


    int


    i=


    0


    ; i<buf_gbk.length; i++)


  74. {


  75. char


    c = (


    char


    )buf_gbk[i];


  76. sb.append( c );

  77. System.out.println(c +

    “:”


    + getHex((


    byte


    )c));


  78. }


  79. String sIso88591 = sb.toString();

  80. System.out.println(

    “sIso88591:”


    );


  81. System.out.println(sIso88591);

  82. System.out.println(

    “showChar(sIso88591):”


    );


  83. showChar(sIso88591);



  84. byte


    [] buf_iso88591 = sIso88591.getBytes(


    “iso-8859-1”


    );


  85. System.out.println(

    “buf_iso88591:”


    );


  86. showBytes(buf_iso88591);

  87. String sUtf_8 =

    new


    String(buf_iso88591,


    “gbk”


    );


  88. System.out.println(sUtf_8);


  89. }



  90. public




    static




    void


    testString_04()


    throws


    Exception


  91. {

  92. System.out.println(

    “s:”


    + s);




  93. byte


    [] buf_gbk = s.getBytes(


    “gbk”


    );


  94. System.out.println(

    “buf_gbk:”


    );


  95. showBytes(buf_gbk);


  96. String sIso88591 =

    new


    String(buf_gbk,


    “iso-8859-1”


    );



  97. System.out.println(

    “sIso88591:”


    );


  98. System.out.println(sIso88591);

  99. System.out.println(

    “showChar(sIso88591):”


    );


  100. showChar(sIso88591);



  101. byte


    [] buf_iso88591 = sIso88591.getBytes(


    “iso-8859-1”


    );


  102. System.out.println(

    “buf_iso88591:”


    );


  103. showBytes(buf_iso88591);

  104. String sGbk =

    new


    String(buf_iso88591,


    “gbk”


    );


  105. System.out.println(sGbk);


  106. }



  107. /**



  108. * @param args



  109. */





  110. public




    static




    void


    main(String[] args)


    throws


    Exception{



  111. //testString();





  112. //testString_02();




  113. testString_04();

  114. }


  115. }

参考资料:

http://my.oschina.net/whp/blog/36846

http://baike.baidu.com/view/2613676.htm



版权声明:本文为wangyanlong0107原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。