我使用UTF-8编码String从byte[]数组创建了一个。 但是,它应该已经使用其他编码创建(Windows-1252)。
String
byte[]
有没有办法将此String转换回正确的编码?
我知道如果可以访问原始字节数组很容易做到,但是就我而言,为时已晚,因为它是由封闭的源库提供的。
关于这是否可行似乎有些困惑,我想我需要提供一个广泛的例子。
该问题声称(初始)输入是byte[]包含Windows-1252编码数据的输入。我称其byte[] ib为“初始字节”。
ib
在此示例中,我将选择德语单词“Bär”(意为熊)作为输入:
byte[] ib = new byte[] { (byte) 0x42, (byte) 0xE4, (byte) 0x72 }; String correctString = new String(ib, "Windows-1252"); assert correctString.charAt(1) == '\u00E4'; //verify that the character was correctly decoded.
(如果您的JVM不支持该编码,则可以改用ISO-8859-1,因为这三个字母(以及大多数其他字母)在这两种编码中位于同一位置)。
问题继续说明,其他一些代码(在我们的影响范围之外)已经byte[]使用UTF-8编码将其转换为字符串(我将其称为String is“输入字符串”)。这String是可用于实现我们目标的 唯一输入 (如果is可用,那将是微不足道的):
is
String is = new String(ib, "UTF-8"); System.out.println(is);
显然这会产生错误的输出“ B”。
目标将是 仅* 提供可用的内容ib(或对其进行正确的解码byte[])。 *is
现在有人声称 _从中is_获取UTF-8编码的字节将返回与初始数组具有相同值的数组:
byte[] utf8Again = is.getBytes("UTF-8");
但这将返回两个字符的UTF-8编码,B并且�在重新解释为Windows-1252时肯定会返回错误的结果:
B
�
System.out.println(new String(utf8Again, "Windows-1252");
该行产生输出“B�”,这是完全错误的(如果初始数组包含非单词“Bür”,则结果也是相同的输出)。
因此, 在这种情况下, 您将无法撤消该操作,因为信息会丢失。
有 是 实际上情况下,这种错误的编码可以撤消。当所有可能的(或至少出现的)字节序列在该编码中有效时,它更有可能起作用。由于UTF-8具有几个字节序列,这些字节序列根本不是有效值,因此您 会 遇到问题。