Java 中文字符串编码之GBK转UTF-8

写过两篇关于编码的文章了,以为自己比较了解编码了呢?!

结果今天又结结实实的上了一课。

以前转来转去解决的问题终归还是简单的情形。即iso-8859-1转utf-8,或者iso-8859-1转gbk,gb2312之类。这种无损转换,一行代码就搞定。

今天遇到了gbk转utf-8。无论怎么转,都是乱码。

一、乱码的原因

gbk的中文编码是一个汉字用【2】个字节表示,例如汉字“内部”的gbk编码16进制的显示为c4 da b2 bf

utf-8的中文编码是一个汉字用【3】个字节表示,例如汉字“内部”的utf-8编码16进制的显示为e5 86 85 e9 83 a8

很显然,gbk是无法直接转换成utf-8,少字节变为多字节,谁知道缺少的字节是什么啊?!

二、转换的办法

有办法实现“有损”转换吗?答案是肯定的。

1.首先将gbk字符串getBytes()得到两个原始字节,转换成二进制字符流,共16位。

2.根据UTF-8的汉字编码规则,首字节以1110开头,次字节以10开头,第3字节以10开头。在原始的2进制字符串中插入标志位。最终的长度从16--->16+3+2+2=24。

3.转换完成,实际情况需要考虑更多因素,例如字符串是汉字和数字的混合体,需要识别处理数字。

三、不要重复发明轮子

这段代码测试可用还很好用,需要的可以参考。

 1 public static String getUTF8StringFromGBKString(String gbkStr) {
 2         try {
 3             return new String(getUTF8BytesFromGBKString(gbkStr), "UTF-8");
 4         } catch (UnsupportedEncodingException e) {
 5             throw new InternalError();
 6         }
 7     }
 8
 9     public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
10         int n = gbkStr.length();
11         byte[] utfBytes = new byte[3 * n];
12         int k = 0;
13         for (int i = 0; i < n; i++) {
14             int m = gbkStr.charAt(i);
15             if (m < 128 && m >= 0) {
16                 utfBytes[k++] = (byte) m;
17                 continue;
18             }
19             utfBytes[k++] = (byte) (0xe0 | (m >> 12));
20             utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
21             utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
22         }
23         if (k < utfBytes.length) {
24             byte[] tmp = new byte[k];
25             System.arraycopy(utfBytes, 0, tmp, 0, k);
26             return tmp;
27         }
28         return utfBytes;
29     }  

PS:有点儿对不住原作者,找了很多代码,一一测试,结果网页都关闭了,如果有大神认领,我一定补充链接,而且深表感谢。

时间: 2024-08-10 19:18:02

Java 中文字符串编码之GBK转UTF-8的相关文章

java中文字符串截取

/** * author geksong <br/> * function 中文字符串相关操作<br/> **/ public class ChinaStringUtil { /** * 判断字符是不是中文字符 * @param c * @return */ public static boolean isChinese(char c) { int ascii = (int)c; if(ascii >= 0 && ascii <= 255) return

JAVA中文字符编码问题

JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用中.网上的分析文章和解决方案都很多,但总是针对某些特定情况的.很多次遇到乱码问 题后, 经过极为辛苦的调试和搜索资料后终于解决,满以为自己已经掌握了对付这些字符乱码怪兽的诀窍.可当过段时间,换了个应用或换了个环境,又会碰到那讨厌的火 星文,并再次无所适从.于是下决心好好整理一下中文字符编码问题,以方便自己记忆,也为其他程序员兄弟们提供一份参考. 首先要了解JAVA处理字符的原理.JAVA使用UNICODE来存储字符数据,处理字符时通常有

遍历文件夹下java文件utf-8编码转gbk编码,解决source insight无法查看中文的错误

#!/bin/sh function conv() { if [ "$(expr match "$1" ".*\.java$")" != "0" ]; then echo "Converting $1 ..." iconv -f utf-8 -t gbk $1 > $1.temp rm $1 mv $1.temp $1 else echo "Skip $1" fi } #深度优先方

python中文字符串编码问题

接口测试的时候,发现接口返回内容是uncodie类型但是包含中文.在使用print进行打印时输出提示错误: UnicodeEncodeError: 'ascii' codec can't encode characters in position 733-738: ordinal not in range(128) 查阅资料发现是由于内容中包含了中文字符,导致unix系统在print解析是无法正常解析导致. 源码如下: def _ejson(con): comm = "echo '%s' | p

Java获取字符串编码方式

直接下载吧: http://files.cnblogs.com/files/xiluhua/BytesEncodingDetectTool.rar

JAVA字符串编码转换常用类

无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题.尤其在web应用中常常需要处理中文字符,这时就需要进行字符串的编码转换,将字符串编码转换为GBK或者GB2312.一.关键技术点:    1.当前流行的字符编码格式有:US-ASCII.ISO-8859-1.UTF-8.UTF-16BE.UTF-16LE.UTF-16.GBK.GB2312等,其中GBK.GB2312是专门处理中文编码的.    2.String的getBytes方法用于按指定编码获取字符串的字节数组,参数指定了解码

将UTF-8编码的文件读出,保存到编码为GBK的文件中

1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import

解决 java “错误:编码GBK 的不可映射字符”

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46583279 public class HelloWorldwww{ public static void main(String args[]){ int num ; // 声明一个整型变量num num = 3 ; // 将整型变量赋值为3 // 输出字符串,这里用"+" 号连接变量 System.out.println("这是数字"+num);

分享万能java字符串编码转换工具类

代码下载地址:http://www.zuidaima.com/share/1795356301560832.htm 原文:分享万能java字符串编码转换工具类 package com.zuidaima.util; import java.io.UnsupportedEncodingException; /** * 转换字符串的编码 */ public class ChangeCharset { /** 7位ASCII字符,也叫作ISO646-US.Unicode字符集的基本拉丁块 */ publ