您的位置:首页 > 编程语言 > Java开发

Java GetBytes 编码方式

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

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

Java代码



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代码



class TestCharset {

public static void main(String[] args)

{

char c = '你';

int i = c;

System.out.println(c);

System.out.println(i);

}

}

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

Java代码



class TestCharset {

public static void main(String[] args) {

new TestCharset().execute();

}

private void execute() {

String s = "Hello!你好!";

byte[] bytesISO8859 =null;

byte[] bytesGBK = null;

try

{

bytesISO8859 =

s.getBytes("iso-8859-1");

bytesGBK = s.getBytes("GBK");

}

catch

(java.io.UnsupportedEncodingException e)

{

e.printStackTrace();

}

System.out.println

("--------------\n 8859 bytes:");

System.out.println("bytes is: " + arrayToString(bytesISO8859));

System.out.println("hex format is:"

+ encodeHex(bytesISO8859));

System.out.println();

System.out.println

("--------------\n GBK bytes:");

System.out.println("bytes is:" + arrayToString(bytesGBK));

System.out.println("hex format is:" + encodeHex(bytesGBK));

}

public static final String

encodeHex (byte[] bytes)

{

StringBuffer buff =

new StringBuffer(bytes.length * 2);

String b;

for (int i=0; i<bytes.length ; i++)

{

b = Integer.toHexString(bytes[i]);

// byte是两个字节的,而上面的Integer.toHexString会把字节扩展为4个字节

buff.append(b.length() > 2 ? b.substring(6,8) : b);

buff.append(" ");

}

return buff.toString();

}

public static final String arrayToString(byte[] bytes) {

StringBuffer buff = new StringBuffer();

for (int i = 0; i < bytes.length; i++) {

buff.append(bytes[i] + " ");

}

return buff.toString();

}

}

执行上面程序将打印出:

--------------
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: