- 浏览: 235402 次
- 性别:
- 来自: 济南
文章分类
最新评论
-
糯米烧麦:
按上文说明ws发布成功了,但浏览器输入url?wsdl报404 ...
使用JAX-WS的Provider和 Dispatch发布WebService的例子 -
gongmingwind:
我设定后就OK了
使用Servlet实现文件下载的时候,避免浏览器自动打开文件 -
fanhang116:
为什么设定了后还是自动打开呢.
使用Servlet实现文件下载的时候,避免浏览器自动打开文件
【GBK转UTF-8】 在很多论坛、网上经常有网友问“ 为什么我使用 new String(tmp.getBytes("ISO-8859-1"), "UTF-8") 或者 new String(tmp.getBytes("ISO-8859-1"), "GBK")可以得到正确的中文,但是使用 new String(tmp.getBytes("GBK"), "UTF-8") 却不能将GBK转换成UTF-8呢?”
参考前面的【Java基础专题】编码与乱码(03)----String的toCharArray()方法测试 一文,我们就知道原因了。因为如果客户端使用GBK、UTF-8编码,编码后的字节经过ISO-8859-1传输,再用原来相同的编码方式进行解码,这个过程是“无损的转换”---- 因为原始和最终的编码方式相同。
但是如果客户端使用GBK编码,到了服务器端要转换成UTF-8,或者相反的过程。想一想,字节还是那些字节,但是编码的规则变了。原来GBK编码后的4个字节要用UTF-8的每个字符3个字节的规则编码,怎么能不乱码呢?
所以从现在开始,不要再犯这种错误了。new String(tmp.getBytes("GBK"), "UTF-8") 这个过程,JVM内部是不会帮你自动对字节进行扩展以适应UTF-8的编码的。正确的方法应该是根据UTF-8的编码规则进行字节的扩充,即手动从2个字节变成3个字节,然后再转换成十六进制的UTF-8编码。
在这个专题的第一篇文章【Java基础专题】编码与乱码(01)---编码基础 开头,我们就已经介绍了这个规则:
①得到每个字符的2进制GBK编码
②将该16进制的GBK编码转换成2进制的字符串(2个字节)
③分别在字符串的首位插入110,在第9位插入10,在第17位插入10三个字符串,得到3个字节
④将这3个字节分别转换成16进制编码,得到最终的UTF-8编码。
Unicode中文“艺”字: 827A
二进制的“艺”字编码:1000 0010 0111 1010
UTF-8的中文编码规则: 1110xxxx 10xxxxxx 10xxxxxx
UTF-8的“艺”字编码: 1110【1000】 10【0010】【01】 10【11】【1010】
UTF-8的转码过程解析: 8对应的1000被填入第一字节剩余的4位。2对应的0010被填入第2字节剩余的前4位。7对应的0111被拆开,前2位01被填入第2字节的后两位,后2位1被填入第3字节的前2位。A对应的1010被填入第3字节的后4位。
UTF-8的最终编码结果:11101000---对应E8;10001001---对应89;10111010---对应BA。所以最终的UTF-8编码就是%E8%89%BA
下面给出一个从网络上得到的Java转码方法,原文链接见:http://jspengxue.javaeye.com/blog/40781。下面的代码做了小小的修改
package example.encoding;
/** *//**
* The Class CharacterEncodeConverter.
*/
public class CharacterEncodeConverter {
/** *//**
* The main method.
*
* @param args the arguments
*/
public static void main(String[] args) {
try {
CharacterEncodeConverter convert = new CharacterEncodeConverter();
byte[] fullByte = convert.gbk2utf8("中文");
String fullStr = new String(fullByte, "UTF-8");
System.out.println("string from GBK to UTF-8 byte: " + fullStr);
} catch (Exception e) {
e.printStackTrace();
}
}
/** *//**
* Gbk2utf8.
*
* @param chenese the chenese
*
* @return the byte[]
*/
public byte[] gbk2utf8(String chenese) {
// Step 1: 得到GBK编码下的字符数组,一个中文字符对应这里的一个c[i]
char c[] = chenese.toCharArray();
// Step 2: UTF-8使用3个字节存放一个中文字符,所以长度必须为字符的3倍
byte[] fullByte = new byte[3 * c.length];
// Step 3: 循环将字符的GBK编码转换成UTF-8编码
for (int i = 0; i < c.length; i++) {
// Step 3-1:将字符的ASCII编码转换成2进制值
int m = (int) c[i];
String word = Integer.toBinaryString(m);
System.out.println(word);
// Step 3-2:将2进制值补足16位(2个字节的长度)
StringBuffer sb = new StringBuffer();
int len = 16 - word.length();
for (int j = 0; j < len; j++) {
sb.append("0");
}
// Step 3-3:得到该字符最终的2进制GBK编码
// 形似:1000 0010 0111 1010
sb.append(word);
// Step 3-4:最关键的步骤,根据UTF-8的汉字编码规则,首字节
// 以1110开头,次字节以10开头,第3字节以10开头。在原始的2进制
// 字符串中插入标志位。最终的长度从16--->16+3+2+2=24。
sb.insert(0, "1110");
sb.insert(8, "10");
sb.insert(16, "10");
System.out.println(sb.toString());
// Step 3-5:将新的字符串进行分段截取,截为3个字节
String s1 = sb.substring(0, 8);
String s2 = sb.substring(8, 16);
String s3 = sb.substring(16);
// Step 3-6:最后的步骤,把代表3个字节的字符串按2进制的方式
// 进行转换,变成2进制的整数,再转换成16进制值
byte b0 = Integer.valueOf(s1, 2).byteValue();
byte b1 = Integer.valueOf(s2, 2).byteValue();
byte b2 = Integer.valueOf(s3, 2).byteValue();
// Step 3-7:把转换后的3个字节按顺序存放到字节数组的对应位置
byte[] bf = new byte[3];
bf[0] = b0;
bf[1] = b1;
bf[2] = b2;
fullByte[i * 3] = bf[0];
fullByte[i * 3 + 1] = bf[1];
fullByte[i * 3 + 2] = bf[2];
// Step 3-8:返回继续解析下一个中文字符
}
return fullByte;
}
}
最终的测试结果是正确的:string from GBK to UTF-8 byte: 中文。
但是这个方法并不是完美的!要知道这个规则只对中文起作用,如果传入的字符串中包含有单字节字符,如a+3中文,那么解析的结果就变成:string from GBK to UTF-8 byte: ?????????中文了。为什么呢?道理很简单,这个方法对原本在UTF-8中应该用单字节表示的数字、英文字符、符号都变成3个字节了,所以这里有9个?,代表被转换后的a、+、3字符。
所以要让这个方法更加完美,最好的方法就是加入对字符Unicode区间的判断
UCS-2编码(16进制) | UTF-8 字节流(二进制) |
0000 - 007F | 0xxxxxxx |
0080 - 07FF | 110xxxxx 10xxxxxx |
0800 - FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
汉字的Unicode编码范围为\u4E00-\u9FA5 \uF900-\uFA2D,如果不在这个范围内就不是汉字了。
【UTF-8转GBK】
道理和上面的相同,只是一个逆转的过程,不多说了
但是最终的建议还是:能够统一编码就统一编码吧!要知道编码的转换是相当的耗时的工作
发表评论
-
Volatile使用场景
2014-11-26 17:39 850Volatile的特性:可见性,但不互斥.怎么理解这句话, ... -
Java线程(四):线程中断、线程让步、线程睡眠、线程合并 .
2014-10-28 15:49 819有人会问:JDK5之后有了更完善的处理多线程问题的类(并发包 ... -
Java线程(三):线程协作-生产者/消费者问题
2014-10-28 15:35 716上一篇讲述了线程的 ... -
Java线程(二):线程同步synchronized和volatile
2014-10-24 18:19 810上篇通过一个简单 ... -
Java线程(一):线程安全与不安全
2014-10-24 18:01 701当我们查看JDK API的时候,总会发现一些类说明写着,线程 ... -
Java线程(七):Callable和Future
2014-10-24 17:51 491接着上一篇继续并发 ... -
final修饰符
2012-07-09 16:30 872final修饰符1.final 可以修饰变量,被fina ... -
super的限制
2012-07-09 15:49 836super的限制1.子类方法不能直接使用 return sup ... -
JAVA继承在处理成员变量和方法时是有区别
2012-07-09 15:27 1058JAVA继承在处理成员变 ... -
System.getProperty()参数大全
2011-09-29 09:33 965内容来源网站: http://blog.sina.com.cn ... -
字符集和编码
2011-07-07 14:48 823很久很久以前,有一群 ... -
【Java基础专题】编码与乱码(07)---native2ascii命令的用法
2011-07-05 11:54 1087【1】native2ascii命令的语 ... -
【Java基础专题】编码与乱码(06)---字符的各种值转换
2011-07-05 11:53 1012package example.encoding; /* ... -
【Java基础专题】编码与乱码(04)---输出时的编码与乱码
2011-07-05 11:45 1275package example.encoding; im ... -
【Java基础专题】编码与乱码(03)----String的toCharArray()方法
2011-07-05 11:43 1205package example.encoding; i ... -
【Java基础专题】编码与乱码(02)---String的getBytes([encoding])方法
2011-07-05 11:41 1057package example.encoding; im ... -
【Java基础专题】编码与乱码(01)---编码基础
2011-07-05 11:30 931Unicode中文“艺”字: 827A二进制的“艺”字编码:1 ... -
JavaEE防止中文乱码的设置
2011-07-04 17:29 1507在基于J2EE的B/S应用中,中文乱码是一个永恒的主题,永远都 ... -
JAVA 序列化
2011-05-21 13:49 865当进行序列化的时候: 首先JVM会先调用writeReplac ...
相关推荐
idea、Eclipse等项目导入.java文件中文乱码完美解决方案:文件夹下所有GBK编码的.java一键转为utf-8,操作方式:将GBK2UTF8.jar文件考到需要转码项目目录,在当前位置运行控制台,输入命令java -jar GBK2UTF8.jar,...
在eclispe的项目中,有存在项目字符集和工作空间字符集不匹配,该jar只能将项目文件中的.java结尾的文件转为utf8编码,并且源文件必须为gbk编码的,否则乱码
老项目采用GBK编码格式,而新项目采用的UTF-8编码格式,如果直接把Java源代码复制到Eclipse中所有的中文信息会出现乱码。所以写了个小的方法类,将java文件的编码格式从GBK转UTF-8
在开发的时候经常碰到这样的情况,需要将原本编码格式为GBK的工程改成UTF-8来编码,设置之后,注释全都乱码了,一个一个改太麻烦,有了这个工具只用运行一下main方法,一键搞定 ps:如果是UTF-8转GBK,或是其他编码...
用于常用编码转换,包括BREW、JAVA等语言UNICODE字符串定义格式,网页编码,GBK及UTF-8的URL编码等
不需要关心接受的字符串编码是UTF_8还是GBK,还是ios-8859-1,自动转换为utf-8编码格式,无需判断字符串原有编码,用法://处理编码String newStr = GetEncode.transcode(oldStr);
java读写excel包括utf8转码为可识别汉字gbk,jxl方式读取excel,生成一个新的excel
可以帮助你把中文转换成UTF-8编码形式,UTF-8编码与中文互转,同时也支持把UTF-8编码过的字符还原成中文,将字符串转换为UTF-8形式,解决在网络传输过程中出现的字符乱码,同时可跨平台使用。
修正之前版本一些UTF-8转换后乱码的Bug 附上NChardet源码 可用于转换java文件为指定格式编码工具(内付源码),自动检测文件的编码类型
在eclipse编程过程中,如果遇到乱码问题,可以讲此工程放置到workspace目录下进行转码,但是使用者需对代码中的文件路径进行相应的修改。 使用时,需将要转码的文件放到一个文件夹中,在workspace中新建一个system...
方便开发者的工程项目编码格式转换,并且转码后不会出现中英文乱码。
有java环境的直接运行就好 ,主要是用来转换文件的编码,比如一个eclipse的默认编码是GBK,另一个eclipse的编码是UTF-8,把GBK的项目拿到utf-8的eclipse去运行,中文肯定乱码,这时需要把GBK的转为utf-8,然后网上也...
如果之前项目类用的编码不统一,或有的是GBK.或是其他的,要一次性转为UTF8编码,又不想造成乱码,直接用本代码即可转换
有java环境的直接运行就好 ,主要是用来转换文件的编码,比如一个eclipse的默认编码是GBK,另一个eclipse的编码是UTF-8,把GBK的项目拿到utf-8的eclipse去运行,中文肯定乱码,这时需要把GBK的转为utf-8,然后网上也...
批量转换文件的二进制编码(用新的文件编码重写文件),如从gbk到utf-8,免除逐个文件全选、复制、右键、属性、改文本文件编码、粘贴、保存之苦(该转换是根据编码设置文件进行转换的,因此更加安全); c.结合上述...
可将UTF-8、GBK、GB2312编码文件相互转换,使之在不同编码坏境种不出现中英文乱码
对所有类型的文件做编码转换,典型的例子,在新建项目的时候忘记改项目编码,项目编写完了改utf-8后,java文件中的中文都会乱码,怎么办呢?完全可以用我的这个类进行转换
取错误文本()”返回的文本是UTF-8编码(应是GB18030编码)。 -------------------------------------------------------------------------------- 易语言5.0 相对于易语言4.x更新说明(2010/02/01): 增加...
* java :UTF-8 * * 数据库: * mysql、oracle、DB2 :UTF-8 * * 开发工具:UTF-8 * 2. 文本文件用统一的字符集 且用字符流读取和写出文本相关文件(最常用) * 3...
encoding="GBK" 编码格式 parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值 的如parse=true,而不是parse="true" 用例 /common/copyright.ftl 包含内容 ...