Java中String与byte[]的转换
String s = "easonjim";//String变量
byte b[] = s.getBytes();//String转换为byte[]
String t = new String(b);//bytep[]转换为String,⽀持传递编码
1、“字符”是由数字来表⽰的
先来重新了解⼀下计算机是如何处理“字符”的,这个原理是⼤家必须记住的,特别是在⽤Java写程序的时候,万万不可模糊。我们知道,计算机把任何东西都⽤数字来表⽰,“字符”也不例外。⽐如我们要显⽰⼀个阿拉伯数字“3”,在我们的PC⾥,其实并不是仅仅⽤⼀个数字3来代表我们要写的“3”,⽽是以⼗六进制的0x33来代表,包括放在内存或者是写到⽂件⾥,其实都是写着0x33的,不信你可以编辑⼀个⽂本⽂件,写⼀个“3”,然后⽤ultraEdit看他的原始码。
2、⼀切“字符”都必定⽤数字+编码表表⽰
这时候,有⼀个问题:为什么⼀定要⽤0x33来代表“3”呢?⽽不⽤0x43来代表呢?或者是直接⽤0x03来代替?其实⽤什么来代表都可以,只不过⼤家都习惯了⽤ASCII编码表(是美国国家信息交换表)来确定各
字符应该是⽤什么数字代表的。同样,为了表⽰中国字,我国也指定了中⽂的编码表,其中最⼴泛使⽤的是GB2312。⽐如中⽂的“当”字,就是⽤0xB5, 0xB1这两个⼋位的数字来表⽰的。所以如果显⽰字符的程序不知道⼀列数字到底是按什么编码表编码的,他也⽆法去判断到底这些是什么⽂字。如果随便⽤⼀个不对的编码表来处理这些数字,处理出来的字符很可能完全是错的。⽐如在英⽂系统上,没有GB2312编码表,送给他⼀个0xB5,0xB1,他就傻傻的当作ASCII来处理(操作系统通常都有⾃⼰默认的编码表),结果显⽰出来就是两个奇怪的符号,因为这两个字在ASCII表⾥就是那两个符号。同样在繁体中⽂系统⾥,他的编码表是BIG5,显⽰出来也是⼀个奇怪的中⽂,不是“当”字。
3、Unicode让全世界都说⼀种语⾔
看完上⾯的⽂字,是否觉得,世界有那么多语⾔,每个都有⾃⼰的⼀套编码表,很⿇烦呢?就算是中⽂,也有两套流⾏的编码表,⼀个是GB2312,⼀个是BIG5。要使⽤不同中⽂的编码的字符时,还要转来转去,的确很⿇烦。不光这个,如果想要写⼀篇包含很多过国⽂字的⽂章,就⿇烦了,必须要让处理这个⽂章的程序知道,哪个字是什么编码标准的。如果你想要在⽂章⾥⼀个字,也必须指定你要的是哪种编码的哪个字。否则,你要⼀个0xB5,0xB1的中⽂“当”字,很可能把同样数字表⽰的⽇⽂、波兰⽂这些不相⼲的字⼀起给你出来,够⿇烦的吧!
所以⼈们想,不如⼤家都⽤同⼀个编码标准吧,各种⽂字都在编码表⾥有⼀席之地,处理⽂字的程序只
需要都按这个编码表来处理就可以了。不过要⼀个编码表⾥包含所有的⽂字,这张表就⼤了,本来英⽂字+数字⼀共只有128个以内。但加上中⽂后,忽然就多了数万个,所以存放⼀个字符需要的⼤⼩也⼤了很多。现在Unicode规定了⼀个字符必须由2个8位数字来表⽰,想想,8x8x8x8x = 65536 ,是多⼤的⼀个数字啊!所以全世界的⽂字才能都包含进去。当然拉,也有⼈说中国字可能都不⽌6万个拉,还要包括别的⽂字,但⼈家外国⼈觉得你们中国⼈常⽤的也没那么多,所以就这么定了,我们也没办法。需要注意的是GB2312和Unicode虽然都是⽤两个8位数来代表⼀个中⽂字,但具体的规格可不⼀样,⽐如0xB5,0xB1在Unicode⾥⾯可不是“当”字,⽽是另外⼀国的⽂字来的。
4、C是如何简洁的处理字符的
我们来谈谈C的字符串。C语⾔诞⽣在Java之前,C语⾔的基本数据类型是没有字符串这个类型的,它只有char[]。也就是C把字符顺序放⼊⼀个字节数组就完了。⽽且C也不管放在数组⾥的是什么⽂字,也不管那些字是按什么编码标准的。⽽且他的char的⼤⼩也不⼀定是8位数字,有时候是16位也可能,这要看具体的机器和操作系统。所以写程序的⼈必须要知道正在处理的char[]的内容到底是按什么编码表表⽰的字符串,要知道如果⽐较两国⽂字是否相同,可是没任何意义的哦!
5、Java是是如何处理字符的
世界总会进步的,Java就是⼀个例⼦。Java终于有了String类了,它是解决字符问题的最好⼯具。在Javc 字符串转数组
a⾥,⼀个基本的要点是:String类对象是不需要指定编码表的!为什么它会⾃⼰知道⼀堆数字各代表什么字符呢?就是因为String⾥的字符信息是⽤Unicode编码存放的。⽽Java为了表⽰字符(注意是单个字符),也有char这个数据类型,⽽且他的⼤⼩是固定2个8位16进制数字长度,也就是0~65535罗。为的就是对应Unicode⾥⾯的⼀个字符。⼤家如果想取⼀个String⾥的按Unicode数字,可以⽤getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) ⽅法取得⼀个char[],这个char[]⾥就是表⽰String字符的,按Unicode编码表编码的数字。
可惜现在绝⼤多数的系统和程序都不是按Unicode来处理字符,⽽Java程序总是要和别的程序和系统交换数据的,所以在接收⼀个字符,或者是发送⼀个字符的时候,就必须要留意当前系统和Unicode的关系了。⽐如你从⽹络或者⽂件接受到⼀数字:0xB5,0xB1,Java程序并不知道这两个字到底是中⽂呢?还是⽇⽂,或者英⽂。你如果不指明这个两个数字的编码表,Java就会按当前系统默认的编码表来处理。如果这两个数字是从中⽂WIN98发出去的,Java程序⼜是在英⽂LINUX上运⾏的,那就出现了所谓的乱码问题了。也就是Java按英⽂的编码表ASCII来处理这两个数字,当通过new String({0xB5,0xB1})得到的String的时候,这个String代表的已经不是中⽂的“当”字,⽽是两个英⽂的奇怪字符了。不过如果你知道这两个数字⼀定是中⽂的话,就可以指定⽤new String({0xB5,0xB1},"GB2312")来处理,这时候新建⽴的String 才真的是⼀个“当”字。当然拉,如果你要把⼀个“当”字的Java的String显⽰在中⽂WIN98上,必须把这个字输出成两个8位数字:
0xB5,0xB1,不管是写成⽂件还是输出到浏览器上,都必须是0xB5,0xB1。如何把“当”字⽤GB2312输出?Bytes("GB2312")就可以拉!所以有⼀点要记住:和外界交换任何信息都是以byte[]来进⾏的!。你可以留意⼀下Java⼤多数的I/O类,都有以byte[]作为参数和返回值的⽅法。不过,也有很多写的⽐较糊涂的程序,没有提供byte[]交换信息的⽅法,害的不同⽂字平台的程序员很头疼。Servlet的Parameter()就是这样。好在有的JSP/SERVLET容易还提供先指定编码表的⽅法,才能⽐较简单的解决这个问题。
6、⽹上关于Java中⽂问题的⼀些错误处理⽅法
⼀个是最常见的,不管什么内容,都⽤new String(...,"ISO-8859-1")来建⽴字符串,然后使⽤的时候按默认的编码格式(通常在服务器上都是英⽂系统)输出字符串。这样其实你使⽤的String并不是按Unicode来代表真正的字符,⽽是强⾏把byte数组复制到String的char[]⾥,⼀旦你的运⾏环境改变,你就被迫要修改⼀⼤堆的代码。⽽且也⽆法在同⼀个字符串⾥处理⼏种不同编码的⽂字。
另⼀个是把⼀种编码格式的字符串,⽐如是GB2312,转换成另⼀种格式的字符串,⽐如UTF-8,然后不指明是UTF-8编码,⽽直接⽤new String(...)来建⽴String,这样放在String⾥⾯的字符也是⽆法确定的,它在不同的系统上代表不同的字符。如果要求别⼈⽤“UTF-8格式”的String来交换信息的时候,其实已经破坏了Java为了兼容各种语⾔所做的规定。这种错误的本质思想是还按写C语⾔的⽅式,把字符串
纯粹当作可以⾃⼰⾃由编码的存储器使⽤,⽽忽略了Java字符串只有⼀种编码格式。如果真的想⾃由编码,⽤byte[]或者char[]就完全了解决问题的了。
参考:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。