Java GetBytes 编码方式

在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->new String()-->显示的过程中,每一步都有编码的转换过程,这个过程总是存在的,只是有的时候用默认的参数进行。

      1.  JAVAC是以系统默认编码读入源文件,然后按UNICODE进行编码的。可以通过指定编码方式改变Javac读入源文件的编码方式。

 

Java代码  收藏代码
  1. javac -encoding GBK Test.java  

 

      2. 在JAVA运行的时候,JAVA也是采用UNICODE编码的,并且默认输入和输出的都是操作系统的默认编码。

      也就是说在new String(bytes[,encode])中,系统认为输入的是编码为encode的字节流,换句话说,如果按encode来翻译bytes才能得到正确的结果,这个结果最后要在JAVA中保存,它还是要从这个encode转换成Unicode,也就是说有bytes-->encode字符-->Unicode字符的转换;而在String.getBytes([encode])中,系统要做一个Unicode字符-->encode字符-->bytes的转换。

3. Java中的编码支持

Java是支持多国编码的,在Java中,字符都是以Unicode进行存储的,比如,“你”字的Unicode编码是“4f60”,我们可以通过下面的实验代码来验证: 

Java代码  收藏代码
  1. class TestCharset          {  
  2.             public static void main(String[] args)  
  3.             {  
  4.             char c = '你';  
  5.             int i = c;  
  6.             System.out.println(c);  
  7.             System.out.println(i);  
  8.             }  
  9.     }   

 不管你在任何平台上执行,都会有相同的输出:20320,20320就是Unicode “4f60”的整数值。其实,你可以反编译上面的类,可以发现在生成的.class文件中字符“你”(或者其它任何中文字串)本身就是以Unicode编码进行存储的:char c = '\u4F60';
     4. 为了避免这种问题,建议大家都在编码中使用String.getBytes(String charset)方法。

Java代码  收藏代码
  1. class TestCharset {  
  2.     public static void main(String[] args) {  
  3.         new TestCharset().execute();  
  4.     }  
  5.   
  6.     private void execute() {  
  7.             String s = "Hello!你好!";  
  8.             byte[] bytesISO8859 =null;  
  9.             byte[] bytesGBK = null;  
  10.             try  
  11.             {  
  12.             bytesISO8859 =  
  13.             s.getBytes("iso-8859-1");  
  14.             bytesGBK = s.getBytes("GBK");  
  15.             }  
  16.             catch  
  17.             (java.io.UnsupportedEncodingException e)  
  18.             {  
  19.             e.printStackTrace();  
  20.             }  
  21.             System.out.println  
  22.             ("--------------\n 8859 bytes:");  
  23.             System.out.println("bytes is:     " + arrayToString(bytesISO8859));  
  24.             System.out.println("hex format is:"  
  25.             + encodeHex(bytesISO8859));  
  26.             System.out.println();  
  27.             System.out.println  
  28.             ("--------------\n GBK bytes:");  
  29.             System.out.println("bytes is:" + arrayToString(bytesGBK));  
  30.             System.out.println("hex format is:" + encodeHex(bytesGBK));  
  31.             }  
  32.   
  33.     public static final String  
  34.             encodeHex (byte[] bytes)  
  35.             {  
  36.             StringBuffer buff =  
  37.             new StringBuffer(bytes.length * 2);  
  38.             String b;  
  39.             for (int i=0; i<bytes.length ; i++)  
  40.             {  
  41.             b = Integer.toHexString(bytes[i]);  
  42.             // byte是两个字节的,而上面的Integer.toHexString会把字节扩展为4个字节  
  43.             buff.append(b.length() > 2 ? b.substring(6,8) : b);  
  44.             buff.append(" ");  
  45.             }  
  46.             return buff.toString();  
  47.             }  
  48.   
  49.     public static final String arrayToString(byte[] bytes) {  
  50.         StringBuffer buff = new StringBuffer();  
  51.         for (int i = 0; i < bytes.length; i++) {  
  52.             buff.append(bytes[i] + " ");  
  53.         }  
  54.         return buff.toString();  
  55.     }  
  56. }  

 

执行上面程序将打印出:

--------------
            8859 bytes:
            bytes is:     72 101 108 108 111 33 63 63 63
            hex format is:48 65 6c 6c 6f 21 3f 3f 3f
            --------------
            GBK bytes:
            bytes is:     72 101 108 108 111 33
            -60 -29 -70 -61 -93 -95
            hex format is:48 65 6c 6c 6f 21 c4 e3 ba c3 a3 a1

可见,在s中提取的8859-1格式的字节数组长度为9,中文字符都变成了“63”,ASCII码为63的是“?”,一些国外的程序在国内中文环境下运行时,经常出现乱码,上面布满了“?”,就是因为编码没有进行正确处理的结果。

 

sourceurl:http://nopainnogain.iteye.com/blog/970628

posted @ 2011-12-19 21:12  hnrainll  阅读(16798)  评论(2编辑  收藏  举报