- 浏览: 241269 次
- 性别:
- 来自: 济南
文章分类
最新评论
-
糯米烧麦:
按上文说明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 895Volatile的特性:可见性,但不互斥.怎么理解这句话, ... -
Java线程(四):线程中断、线程让步、线程睡眠、线程合并 .
2014-10-28 15:49 872有人会问:JDK5之后有了更完善的处理多线程问题的类(并发包 ... -
Java线程(三):线程协作-生产者/消费者问题
2014-10-28 15:35 753上一篇讲述了线程的 ... -
Java线程(二):线程同步synchronized和volatile
2014-10-24 18:19 845上篇通过一个简单 ... -
Java线程(一):线程安全与不安全
2014-10-24 18:01 741当我们查看JDK API的时候,总会发现一些类说明写着,线程 ... -
Java线程(七):Callable和Future
2014-10-24 17:51 532接着上一篇继续并发 ... -
final修饰符
2012-07-09 16:30 917final修饰符1.final 可以修饰变量,被fina ... -
super的限制
2012-07-09 15:49 868super的限制1.子类方法不能直接使用 return sup ... -
JAVA继承在处理成员变量和方法时是有区别
2012-07-09 15:27 1093JAVA继承在处理成员变 ... -
System.getProperty()参数大全
2011-09-29 09:33 1015内容来源网站: http://blog.sina.com.cn ... -
字符集和编码
2011-07-07 14:48 872很久很久以前,有一群 ... -
【Java基础专题】编码与乱码(07)---native2ascii命令的用法
2011-07-05 11:54 1130【1】native2ascii命令的语 ... -
【Java基础专题】编码与乱码(06)---字符的各种值转换
2011-07-05 11:53 1069package example.encoding; /* ... -
【Java基础专题】编码与乱码(04)---输出时的编码与乱码
2011-07-05 11:45 1337package example.encoding; im ... -
【Java基础专题】编码与乱码(03)----String的toCharArray()方法
2011-07-05 11:43 1250package example.encoding; i ... -
【Java基础专题】编码与乱码(02)---String的getBytes([encoding])方法
2011-07-05 11:41 1124package example.encoding; im ... -
【Java基础专题】编码与乱码(01)---编码基础
2011-07-05 11:30 964Unicode中文“艺”字: 827A二进制的“艺”字编码:1 ... -
JavaEE防止中文乱码的设置
2011-07-04 17:29 1569在基于J2EE的B/S应用中,中文乱码是一个永恒的主题,永远都 ... -
JAVA 序列化
2011-05-21 13:49 908当进行序列化的时候: 首先JVM会先调用writeReplac ...
相关推荐
### JAVA字符编码详解:Unicode, ISO-8859-1, GBK, UTF-8 及其相互转换 #### 一、引言 在Java编程中,字符编码的管理和转换是一项基本而又重要的任务。不同的编码标准适用于不同的场景,而理解和掌握这些编码之间...
- 类似地,当从UTF-8转换到ISO-8859-1时,也会出现类似的情况: ```java String utf8Str = "中文"; byte[] isoBytes = utf8Str.getBytes("UTF-8"); String isoStr = new String(isoBytes, "ISO-8859-1"); // ...
idea、Eclipse等项目导入.java文件中文乱码完美解决方案:文件夹下所有GBK编码的.java一键转为utf-8,操作方式:将GBK2UTF8.jar文件考到需要转码项目目录,在当前位置运行控制台,输入命令java -jar GBK2UTF8.jar,...
这篇博客文章“eclipse中class乱码GBK-UTF-8转换工具”正是为了解决这个问题。 GBK是GB2312的扩展,包含了更多的汉字和其他字符,主要在中国大陆使用。UTF-8则是一种广泛使用的Unicode编码,支持世界上几乎所有的...
例如,如果数据库是UTF-8,JSP是GBK,可以使用 `new String(rs.getBytes(1),"UTF-8")` 将数据库中的UTF-8字节流转换为GBK字符串。反之,如果JSP是UTF-8,数据库是GBK,需要先将GBK字符串转换为字节流,然后再次转换...
GBK与UTF-8之间的转换是一种常见的编码转换过程,在很多情况下,我们需要将GBK编码的字符串转换成UTF-8编码的字符串。然而,这种转换过程并不简单,需要我们了解编码的基本原理和规则。 首先,让我们了解一下GBK和...
使用这些资源,用户可以方便地在UTF-8和GBK之间进行文件编码的转换,解决编码不一致带来的问题,确保文本数据的正确性和可读性。对于经常处理中文文件的IT专业人士来说,理解和掌握编码转换技巧是非常必要的。
老项目采用GBK编码格式,而新项目采用的UTF-8编码格式,如果直接把Java源代码复制到Eclipse中所有的中文信息会出现乱码。所以写了个小的方法类,将java文件的编码格式从GBK转UTF-8
总的来说,解决Eclipse中GBK转UTF-8乱码问题的关键在于正确设置工作空间、项目、源代码和资源文件的编码,并且适时使用辅助工具进行批量转换。通过这些方法,可以避免编码不一致导致的乱码问题,提高开发效率。在...
在eclispe的项目中,有存在项目字符集和工作空间字符集不匹配,该jar只能将项目文件中的.java结尾的文件转为utf8编码,并且源文件必须为gbk编码的,否则乱码
Eclipse是一款广泛使用的Java开发集成环境,而GBK和UTF-8是两种常见的字符编码格式。在处理源代码时,编码的选择至关重要,因为它直接影响到字符的正确显示和处理。GBK编码是中国大陆广泛使用的汉字编码标准,它包含...
本文将详细解析“简单的UTF-8与GBK之间相互转码工具”,并介绍相关的编码概念和实现方法。 首先,让我们理解编码的基础知识。字符编码是用来表示文本的规则,常见的有ASCII、GBK(GB2312的扩展)、UTF-8等。ASCII是...
Java源码编码转换器是一款实用工具,主要用于将Java源代码文件从GBK编码转换为UTF-8编码,或者从UTF-8编码转换为GBK编码。在软件开发过程中,尤其是在处理中文字符时,编码问题是一个常见的挑战。GBK是中文环境下...
本文将针对标题中的几种常见编码格式(GBK、ISO 8859-1、UTF-8)以及如何解决由这些编码方式引发的乱码问题进行深入探讨。 #### 一、编码概述 1. **GBK编码**:GBK是GB2312标准的扩展,支持简体中文,是Microsoft ...
在开发的时候经常碰到这样的情况,需要将原本编码格式为GBK的工程改成UTF-8来编码,设置之后,注释全都乱码了,一个一个改太麻烦,有了这个工具只用运行一下main方法,一键搞定 ps:如果是UTF-8转GBK,或是其他编码...
3. **转换编码**:对于检测到GBK编码的文件,使用`java.nio.file.Files`类的`readAllBytes`和`write`方法,配合`java.nio.charset.StandardCharsets`中的`UTF_8`常量,将文件内容从GBK编码转换为UTF-8编码。...
总的来说,从GBK编码转换到UTF-8是解决Java源代码在Eclipse中可能出现的乱码问题的有效方法。通过编写Java程序或使用Eclipse插件,可以方便地对整个项目进行批量转换,确保所有文件都以正确的编码格式存储和处理。...
"UTF-8 编码转换详解" 1. UTF-8 编码的重要性:在 WEB 开发中,UTF-8 编码扮演着非常重要的角色,特别是在传递中文时,必须经过编码的动作,否则可能会出现乱码的情况。 2. 使用 URLEncoder.encode() 方法:在 ...
该工具在之前的版本基础上进行了优化,修复了UTF-8转换后可能出现的乱码错误,确保了转换的准确性和稳定性。 在软件开发中,编码问题是一个常见的困扰,特别是当项目涉及到多种编码格式时。GBK是中国大陆广泛使用的...
当一个工程项目从GBK编码或其它非UTF-8编码格式需要转换为UTF-8时,开发者可能会遇到中英文乱码问题。Eclipse作为流行的Java集成开发环境,提供了便捷的插件来解决这类问题。 在Eclipse中进行批量转码通常涉及以下...