首页 新闻 会员 周边

java 默认unicode编码,任何字符串都默认了unicode,为什么GBK转UTF-8还会乱码?

0
悬赏园豆:10 [待解决问题]

            String name = "我来了";

             String str = new String(name.getBytes("x"),"xxx");

             不管jvm这里默认的编码是GBK还是UTF-8还是其他编码,name.getBytes("x")java都会自动帮你转成Unicode编码,然后再以x的编码方式转成xxx的编码字符集。

       例如:如何GbK转成UTF-8,真正的核心问题是GBK怎么转成unicode(无法直接转只能找GBK和unicode对照表),转成unicode以后转utf-8就好转了(因为有规律)。java特殊因为java 字符串都是默认unicode的(生产的class文件都是 unicode字符集),所以无论你name.getBytes("xx")是什么编码得到的unicode值都是unicode字符集的正确值。(既然java字符默认都转成了unicode那么为什么GBK转UTF-8为什么还是乱码?java都做到默认转unicode编码了可以实现不乱码了,不知内部为什么?),所有有人在java语言中也有实现GBK转UTF-8,其实就是直接unicode转utf-8。

   这里有一篇GBK2utf-8的文章,http://www.blogjava.net/pengpenglin/archive/2010/02/22/313669.html

,重新描述一下我的问题?我知道xxx.getBytes("xx"),这个java会自动转成unicode的,不管你系统设置了什么编码。那么大家知道unicode转utf-8是肯定不会乱码的,问题来了,java中其实实现new  String (xxx.getBytes("GBK"),UTF-8)其实会乱码的,那么为什么?别说原理其实我知道GBK转Utf-8肯定会乱码?编码规则都不一样?关键是java既然实现了任何编码都默认转成了unicode理论直接转utf-8不会乱码了呀?

淡泊名利的主页 淡泊名利 | 初学一级 | 园豆:181
提问于:2016-04-11 14:53
< >
分享
所有回答(2)
0

你得看文件到底是用什么编码存储的啊,如果是UTF-8,结果你这里使用GBK来解析,由于他们的字节是不一样的,就算你在代码中转成了UTF-8,它也不认识了!....所以你需要先看一下文件的编码、系统的编码、代码getBytes()的编码、newString的编码.....这样一级一级的来。

比如,如果你的文件编码为ANSI或者UTF-8,最好是使用ISO-8859-1先按照字节来读取,然后转成对应的GB-2312或者UTF-8。

 new String(str.getBytes("ISO-8859-1"), "UTF-8");

另外,你的红色字体真刺眼!

xingoo | 园豆:711 (小虾三级) | 2016-04-14 09:04
0

试着解释一下:

字符串对象在计算机里存储传输是字节流,也就是byte[]。字符串是什么呢,字符串是字节流+编码。如果只给你一串字节流,不告诉你编码是什么,你是不可能看到正确的字符串的。

这个世界上有很多种编码,ascii、gbk、utf-8……浏览器把字节流传给服务器,如果浏览器按照gbk编码,服务器按照utf-8解码,结果就是乱码。

java是unicode内码,当jvm执行String name="我来了";内存的字节流是unicode编码。

然后看一下String类的文档,先看构造函数:

public String(byte[] bytes, Charset charset)

Constructs a new String by decoding the specified array of bytes using the specified charset. The length of the new String is a function of the charset, and hence may not be equal to the length of the byte array.
构造函数会按照charset参数对字节流进行编码,得到一个字符串。
 
再看看getByte:
public byte[] getBytes(Charset charset)
Encodes this String into a sequence of bytes using the given charset, storing the result into a new byte array.
把字符串按照chatset参数转成字节流。
 
当你运行name.toBytes("xx"),你把“我来了”按照xx编码转成字节流,你再运行new String(bytes, "xxx"),你又把xx编码的字节流按照xxx编码转成字符串,当然是乱码了。
 
那我们为什么有时候要转码呢?
比如我们写一个服务器程序,从浏览器得到一个字符串。浏览器是按照utf-8编码传输这个字符串的,但是我们的tomcat收到字节流却用gbk解码,于是我们的jsp里面就会看到一个乱乱的string。不要紧,只要把这个乱乱的string按照gbk重新转成字节流,再按照utf-8编码,不就恢复了吗。new String(s.toBytes("gbk"),"utf-8")
 
当然最好是调一下tomcat的设置,让tomcat直接用utf-8编码收到的字节流,就不用在jsp代码里转了。
小陆 | 园豆:365 (菜鸟二级) | 2016-04-22 01:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册