转:Java中String与byte[]的转换
原文地址:http://blog.csdn.net/llwan/article/details/7567906
String s = "fs123fdsa";//String变量 byte b[] = s.getBytes();//String转换为byte[] String t = new String(b);//bytep[]转换为String
做JAVA经常会碰到中文乱码问题,还有各种编码的问题,特别是String类的内容需要重新编码的问题。要解决这些问题,必须了解清楚JAVA对于字符串是怎么处理的。
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类了,它是解决字符问题的最好工具。在JAVA里,一个基本的要点是: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输出?String.getBytes("GB2312")就可以拉!所以有一点要记住:和外界交换任何信息都是以byte[]来进行的!。你可以留意一下JAVA大多数的I/O类,都有以byte[]作为参数和返回值的方法。不过,也有很多写的比较糊涂的程序,没有提供byte[]交换信息的方法,害的不同文字平台的程序员很头疼。Servlet的HttpRequest.getParameter()就是这样。好在有的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[]就完全了解决问题的了。
以上,除了是解决JAVA中文问题的基础知识外,也是多年前应该掌握的计算机基础知识。温故而知新,以期共勉。
转:Java中String与byte[]的转换的更多相关文章
- java中string与byte[]的转换
1.string 转 byte[] byte[] midbytes=isoString.getBytes("UTF8"); //为UTF8编码 byte[] isoret = sr ...
- 关于==和equals()方法&Java中string与char如何转换&String,StringBuffer
1.对于基本数据类型,可以直接使用==和!=进行内容比较 如:int x=30; int y=30; x==y; //true 基本数据类型 简单类型(基本类型) bo ...
- Java中String和byte[]间的转换浅析
Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...
- Java中String和byte[]间的 转换浅析
Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...
- Java中String和byte[]间的 转换
数据库的字段中使用了blob类型时,在entity中此字段可以对应为byte[] 类型,保存到数据库中时需要把传入的参数转为byte[]类型,读取的时候再通过将byte[]类型转换为String类型. ...
- java中string与byte[]之间的转化分析
背景:最近接触zookeeper的java开发,由于zookeeper中传的好像都是byte[]的数据(需要进一步确认),好多情况下都需要进行转换. 1)和zookeeper原生API不同,通过zkc ...
- 116、Java中String类之大小写转换
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- Java 中 String 的构造方法
String 对于所有 Java 程序员来说都不会陌生,几乎每天甚至每个程序都会和 String 打交道,因此将 String 的常用知识汇集在此,方便查阅. 概叙: Java 中是如此定义 Stri ...
- Java中String转换Double类型 Java小数点后留两位
Java中String转换Double类型 double num1 = 0.0; String qq = "19.987"; num1 = Double.valueOf(qq.to ...
随机推荐
- xocodebulid 自动化打包 解决提示 ld: library not found for -lPods 问题
如果你的项目用到cocopod 第三方库.使用xcodebulid 估计会出现 ld: library not found for -lPods 以下 是我的解决办法 xcodebuild -work ...
- C++的iterator与const_iterator
所有的标准库容器都定义了相应的迭代器类型.迭代器对所有的容器都适用,现代 C++ 程序更倾向于使用迭代器而不是下标操作访问容器元素. 1.iterator,const_iterator作用:遍历容器内 ...
- ES6模块的import和export用法
ES6之前已经出现了js模块加载的方案,最主要的是CommonJS和AMD规范.commonjs主要应用于服务器,实现同步加载,如nodejs.AMD规范应用于浏览器,如requirejs,为异步加载 ...
- /etc/ssh/sshd_config 关建字:PermitRootLogin no 禁示以root身份登录服务器
这种情况,不会影响,普通用户su到root
- iOS 添加功能引导图
iOS 添加功能引导图 首次安装app之后,打开app首页,有一张功能引导图,其实最简单的一种做法是,直接在这个首页上加一个蒙层图片. 在蒙层上用气泡显示文字注明功能介绍,这个蒙层图片,让你们的UI设 ...
- DIOCP开源项目-DIOCP3直接发送对象,帮你处理粘包问题
该DEMO演示,如何在客户端与服务端之间直接传递TStream对象,让你专注于处理数据逻辑,可以忽略处理网络传输间粘包的问题. 上面由服务端向所有的客户端推送一个消息TMemoryStream对象(该 ...
- 循环遍历li并获取其自定义属性的方法
var lists = $('.list'); for (var j = 0; j < lists.length; j++) { var index = $('.list').eq(j).att ...
- vim 配色(mac)
1.进入当前用户目录,新建 .vimrc ,并加入如下内容: cd / vim .vimrc 2.开启行号 选择颜色 #开启行号 set nu #选择颜色 colorscheme desert syn ...
- 【Deep Learning】Hinton. Reducing the Dimensionality of Data with Neural Networks Reading Note
2006年,机器学习泰斗.多伦多大学计算机系教授Geoffery Hinton在Science发表文章,提出基于深度信念网络(Deep Belief Networks, DBN)可使用非监督的逐层贪心 ...
- Yum Priorities
简介 Linux 发行版比较多,同时还有很多个人或组织维护了某些特定用途的安装/升级源.Yum Priorities 插件可以用来强制保护源.它通过给各个源设定不同的优先级,使得系统管理员可以将某些源 ...