java 多次以不同字符集编码解码后回不来的问题。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 多次以不同字符集编码解码后回不来的问题。相关的知识,希望对你有一定的参考价值。

String a="中";
//一:
a=new String(a.getBytes("UTF-8"), "GBK");
a=new String(a.getBytes("GBK"), "UTF-8");
//二:
a=URLEncoder.encode(a, "UTF-8");
a=URLDecoder.decode(a, "GBK");
a=URLEncoder.encode(a, "GBK");
a=URLDecoder.decode(a, "UTF-8");

这两种写法应该一样吧。。
Q:别人给我的值是new String("中".getBytes("UTF-8"), "GBK"),有没办法将值还原回"中"

//一:
a=new String(a.getBytes("UTF-8"), "GBK");
a=new String(a.getBytes("GBK"), "UTF-8");
对于这一种情况,你之所以输出的是乱码是因为a.getBytes("UTF-8")的意思是按"UTF-8"的编码方式把字符串a转换成为字节数组,new String(a.getBytes("UTF-8"), "GBK")的意思是用"GBK"的编码方式来解释a.getBytes("UTF-8")得到的字节数组来生成字符串。而不是用"GBK"的方式来编码。所以当然是输出乱码。
//二:
a=URLEncoder.encode(a, "UTF-8");
a=URLDecoder.decode(a, "GBK");
a=URLEncoder.encode(a, "GBK");
a=URLDecoder.decode(a, "UTF-8");
你可以试一试下面的方式:
a="中";
a=URLEncoder.encode(a, "UTF-8");
a=URLDecoder.decode(a, "UTF-8");
System.out.println(a);

a=URLEncoder.encode(a, "GBK");
a=URLDecoder.decode(a, "GBK");
System.out.println(a);追问

重新问,别人给我的值是new String("中".getBytes("UTF-8"), "GBK"),有没办法将值还原回"中"

追答

new String("中".getBytes("UTF-8"), "GBK")这个写法本身就有问题,你想把“中”按UTF-8转换成字节数组,然后用“GBK"的方式解释这个字节数组得到的字符串是什么。若果你实在想要怎么做,你可读一下String源码看一看new String("中".getBytes("UTF-8"), "GBK")是怎么做的,看能不能找到什么方法把它倒过来。

参考技术A 对,一样啊,会存在回不来的问题?我去试试。追问

你看下最后的a是什么,采用方法1或者2

追答

你编码和解码要用相同的编码集,这样才不会乱码啊。
你用 UTF-8 编码,却用 GBK 解码,肯定会乱码呀。
按照相同的编码集进行编码然后解码,结果不会乱码,我试过了。

追问

重新问,别人给我的值是new String("中".getBytes("UTF-8"), "GBK"),有没办法将值还原回"中"

追答

不行,编码和解码的字符集不同。很明显啊这个

参考技术B 一样的,那么你的问题是什么追问

重新问,别人给我的值是new String("中".getBytes("UTF-8"), "GBK"),有没办法将值还原回"中"

如何以正确的方式编码和解码字符[重复]

【中文标题】如何以正确的方式编码和解码字符[重复]【英文标题】:How to encode and decode characters in the right way [duplicate] 【发布时间】:2015-12-07 02:23:39 【问题描述】:

我正在开发一个使用编码为UTF-8 的网站。 服务端采用Java开发,数据库采用Windows-1252编码。

如何正确编码字符,以便它们在数据库查看器和客户端都能正确显示?

编辑

代码如下:

Class.forName("com.pervasive.jdbc.v2.Driver");

Connection conn = DriverManager.getConnection("jdbc:pervasive://XXX.XXX.XXX.XXX/TEST","xxxx", "xxxxx");

Statement stmt = conn.createStatement();

String sql = "INSERT INTO MyTest (COL1, COL2) VALUES (99999, 'Ó 456789 ñÑ; ° - + ( _ . - / \\ & <' )";
stmt.executeUpdate(sql);

数据库查看器显示:? 456789 ??; ? - + ( _ . - / \\ &amp; &lt; 而不是Ó 456789 ñÑ; ° - + ( _ . - / \\ &amp; &lt;

SELECT被执行时,字符串? 456789 ??; ? - + ( _ . - / \\ &amp; &lt;被检索

【问题讨论】:

从个人经验来看,在不遭受某种损失的情况下,没有真正的好方法。一种可能的解决方法是让您的数据在数据库中存储编码的 HTML 实体(例如 © 或 € 用于版权徽标),并期望这些在数据库查看器中显示为这样,同时期望在代码中处理它们在 Java 端,并将它们转换为必要的格式。这很糟糕,但它强调了对符合 Unicode 的数据库技术的需求。 @ShotgunNinja 你混淆了 HTML escaping 和字符集 byte[] 编码,这是完全不同的问题。 不,我不是。这里的目标是在两端都有可显示的字符/代码点,如果我理解正确的话,其中一些超出了 Windows-1252 的可表示范围。虽然 Unicode 是为此而设计的,但在最新版本 12 之前的 Pervasive SQL 服务器中不允许使用它,因此我们需要提出一种不同的解决方案,该解决方案可以在 DB 查看器以及 Java 和更高版本中运行网络。非 Windows-1252 表示的代码点的 HTML 实体编码是一种解决方法,而不是此问题的解决方案 我认为问题是由于 Oracle pre-10g 和 Pervasive pre-v12 都没有 decent JDBC 实现来正确处理底层数据令人讨厌的情况(即,由单字节代码页表示,但包含多字节字符,就像我之前的经验一样)。 您混淆了Unicode 代码点规范,它不是编码与编码UTF-8UTF-16UTF-32Windows-1252 是所有代表相同Unicode 代码点的编码映射,但略有不同。某些东西如何显示文本是客户端解释它并显示它的问题,而不是数据的来源。 【参考方案1】:

在 Java 中 String 在内部使用 UTF-16

如果你有一个普通的 Java String,你不需要做任何事情,如果你在插入语句中将它作为 String 插入,你的 JDBC 驱动程序会将 Java String 透明地转换为它使用的任何编码。

当您阅读 ResultSet.getString() 时,它会透明地返回 Java String

如果不是这种情况,则说明应用程序中的某些内容配置不正确,并且插入的错误数据不是它所说的编码。垃圾进/垃圾出。

当您需要担心编码/解码时:

在将文本数据读/写到只接受byte[] 的文件或套接字时,您只需要担心转换byte[] 编码。

使用代表文本的byte[] 时,您需要使用new String(bytes,Charset)byte[] b = string.getBytes(Charset); 分别指定源/目标String 传入和需要传出的任何编码。

永远不要依赖默认编码:

永远不要使用new String(byte[]).getBytes(),它们使用default 编码,因为它可以改变的所有方式对你的代码都是不透明的,所以你得到的都是废话。

微妙的问题是UTF-8Windows-1252 和其他几个编码是ASCII 的超集,并且在此范围内也相互重叠。因此,如果您使用default 编码,一切可能看起来工作正常,然后当您摄取/导出一些包含non-ASCII 范围字符的byte[] 时,事情就会爆炸。

总结:

    切勿使用 byte[] 表示文本,除非某些 API 要求您这样做。 从不依赖默认编码,即使您认为自己知道它是什么。 总是在从byte[]byte[] 转换时指定Charset切勿Charset 编码与URL/URI/HTML/XML 转义混为一谈。 Unicode 不是编码。

【讨论】:

感谢您的回复!这似乎是一个配置问题。请检查上述问题的编辑,

以上是关于java 多次以不同字符集编码解码后回不来的问题。的主要内容,如果未能解决你的问题,请参考以下文章

java.util.Base64解码然后编码产生不同的字符串

理解字符串编码/解码Java

python入门:字符编码

如何以正确的方式编码和解码字符[重复]

告别乱码,针对GBKUTF-8两种编码的智能URL解码器的java实现(转)

java web开发,页面处理Base64编码