1

我有一个“windows1255”编码的字符串,有什么安全的方法可以将它转换为“UTF-8”

字符串,反之亦然?

一般来说,是否有一种安全的方式(意味着数据不会被损坏)在

Java中的编码?

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

如果原始字符串未编码为“UTF-8”,数据是否会损坏?

4

2 回答 2

2

您不能将StringJava 中的对象正确编码为 UTF-16 以外的任何内容 - 因为这是规范定义的那些对象的唯一编码。当然,您可以做一些不愉快的事情,例如将 1252 个值放入 char[] 并从中创建一个 String,但很快就会出错。

您可以拥有以各种不同方式编码的 byte[],您可以使用采用 Charset 的构造函数将它们与 String 进行转换,并getBytes在代码中使用 as。

因此,您可以使用 String 作为中间体进行转换。我不知道在 JDK 中进行直接转换的任何方式,但在实践中中间可能不会太昂贵。

关于往返转换 - 通常情况下,您可以在编码之间进行转换而不会丢失数据。只有少数编码可以处理所有的 Unicode 字符(例如 UTF 系列、GB18030 等)——而许多传统字符集只编码一小部分。除非您确定输入属于可表示集,否则您无法在不丢失数据的情况下安全地往返这些字符集。

于 2013-02-03T11:12:01.573 回答
1

字符串试图成为一个抽象字符序列,从用户的角度来看,它没有任何编码。当然,它必须有一个内部编码,但这是一个实现细节。

将 String 编码为 UTF-8,然后将结果解码为 UTF-8 是没有意义的。这将是无操作的,因为:

(new String(str.getBytes("UTF-8"), "UTF-8") ).equals(str) == true;

但是在某些情况下,String 抽象会分崩离析,以上将是“有损”转换。由于内部实现细节,一个字符串可以包含不成对的 UTF-16 代理,这些代理不能用 UTF-8(或任何编码,包括内部 UTF-16 编码*)表示。所以它们会在编码中丢失,当你解码回来时,你会得到没有无效的未配对代理的原始字符串。

我可以从你的问题中得到的唯一信息是,你有一个将二进制数据解释为 Windows-1255 的字符串结果,它应该在 UTF-8 中解释。要解决此问题,您必须找到此问题的源并明确使用 UTF-8 解码。

但是,如果您仅从误解中得到字符串,那么您实际上无法做任何事情,因为在 Windows-1255 中没有表示太多字节并且不会将其放入字符串中。

如果不是这种情况,您可以通过以下方式完全恢复原始预期消息:

new String( str.getBytes("Windows-1255"), "UTF-8");

* 实际上,Java 允许不成对的代理项存在于其字符串中实际上是错误的,因为它不是有效的 UTF-16

于 2013-02-03T14:11:21.993 回答