编码问题

时间:2013-02-03 10:59:23

标签: java encoding character-encoding

我有一个“windows1255”编码的字符串,是否有任何安全的方法可以将其转换为“UTF-8”

字符串,反之亦然?

一般来说,在

之间进行转换是有安全的方式(意味着数据不会被损坏)

Java中的编码?

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

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

2 个答案:

答案 0 :(得分:2)

您不能将Java中的String对象正确编码为UTF-16以外的任何对象 - 因为这是规范定义的那些对象的唯一编码。当然你可以做一些不好的事情,比如在char []中放入1252个值并从中创建一个String,但事情会立即出错。

你可以拥有的是以各种不同方式编码的byte [],你可以使用构造函数将它们转换为String,使用Charset,并在代码中使用getBytes

因此,您可以使用String作为中间件进行转换。我不知道JDK中有什么方法可以进行直接转换,但实际上中间体可能不会太昂贵。

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

答案 1 :(得分:1)

String正在尝试成为一系列抽象字符,从视角来看它没有任何编码 其用户当然,它必须有内部编码,但这是一个实现细节。

将String编码为UTF-8,然后将结果解码为UTF-8是没有意义的。这将是no-op,在那:

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

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

我可以从你的问题中得到的唯一一点就是你将二进制数据解释为Windows-1255时会得到一个String结果,它应该用UTF-8解释。 要解决此问题,您必须转到此源并明确使用UTF-8解码。

但是,如果您只是因为误解而导致字符串结果,那么您无法真正做任何事情,因为在Windows-1255中这么多字节没有表示,并且没有将其转换为字符串。

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

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

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