Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;“固定”;Java中的字符串编码_Java_Encoding - Fatal编程技术网

&引用;“固定”;Java中的字符串编码

&引用;“固定”;Java中的字符串编码,java,encoding,Java,Encoding,我使用UTF-8编码,从字节[]数组创建了一个字符串。 但是,它应该使用另一种编码(Windows-1252)创建 有没有办法将此字符串转换回正确的编码 我知道,如果您可以访问原始字节数组,这很容易做到,但在我的情况下,这太晚了,因为它是由一个封闭源代码库提供的。您可以使用这个 您需要的字符集应该在rt.jar中定义(根据)您想要做的是不可能的。一旦有了Java字符串,有关字节数组的信息就会丢失。您可能有幸进行了“手动转换”。创建所有windows-1252字符及其到UTF-8的映射的列表。然后

我使用UTF-8编码,从
字节[]
数组创建了一个
字符串。
但是,它应该使用另一种编码(Windows-1252)创建

有没有办法将此字符串转换回正确的编码

我知道,如果您可以访问原始字节数组,这很容易做到,但在我的情况下,这太晚了,因为它是由一个封闭源代码库提供的。

您可以使用这个


您需要的字符集应该在rt.jar中定义(根据)

您想要做的是不可能的。一旦有了Java字符串,有关字节数组的信息就会丢失。您可能有幸进行了“手动转换”。创建所有windows-1252字符及其到UTF-8的映射的列表。然后迭代字符串中的所有字符,将它们转换为正确的编码

编辑:
正如一位评论人士所说,这是行不通的。当您将Windows-1252字节数组转换为UTF-8时,必然会出现编码异常。(请参阅和)。

由于对这是否可能存在一些混淆,我认为我需要提供一个广泛的示例

该问题声称(初始)输入是包含编码数据的
字节[]
。我将其称为
byte[]
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,因为这三个字母(以及大多数其他字母)在这两种编码中的位置相同)

问题是,其他一些代码(不在我们的影响范围内)已经使用UTF-8编码将
字节[]
转换为字符串(我称
字符串
为“输入字符串”)。该
String
是可用于实现我们目标的唯一输入(如果
is
可用,它将是微不足道的):

这显然会产生不正确的输出“B”�".

目标是产生
ib
(或该
字节[]
的正确解码),只有可用

现在有人声称,从
is
获取UTF-8编码字节将返回一个与初始数组值相同的数组:

byte[] utf8Again = is.getBytes("UTF-8");
但是它返回两个字符的UTF-8编码
B
并在重新解释为Windows-1252时返回错误的结果:

System.out.println(new String(utf8Again, "Windows-1252");
这一行产生输出“Bèè½”,这是完全错误的(如果初始数组包含非单词“Bür”,则结果也是相同的)

因此在这种情况下无法撤消操作,因为信息丢失


事实上,在某些情况下,这样的错误编码是可以撤销的。如果一切可能的话(或者至少发生了),这种错误编码更有可能奏效字节序列在该编码中是有效的。由于UTF-8有几个字节序列根本不是有效值,因此您将遇到问题。

我尝试了这个方法,但出于某种原因它起了作用

修复编码问题的代码(它不能完美工作,我们将很快看到):

结果是:

 input: …Und ich beweg mich (aber heut nur langsam)
 fixed: …Und ich beweg mich (aber heut nur langsam)
下面是另一个例子:

 input: Waun da wuan ned wa (feat. Wolfgang Kühn)
 fixed: Waun da wuan ned wa (feat. Wolfgang Kühn)
下面是正在发生的事情以及为什么上面的技巧似乎有效:

  • 原始文件是UTF-8编码的文本文件(逗号分隔)
  • 该文件是用Excel导入的,但用户错误地输入了Windows 1252编码(这可能是他或她的计算机上的默认编码)
  • 用户认为导入成功,因为ASCII范围内的所有字符看起来都正常
  • 现在,当我们试图“逆转”这个过程时,会发生以下情况:

     // we start with this garbage, two characters we don't want!
     String input = "ü";
    
     final Charset cp1252 = Charset.forName("windows-1252");
     final Charset utf8 = Charset.forName("UTF-8");
    
     // lets convert it to bytes in windows-1252:
     // this gives you 2 bytes: c3 bc
     // "Ã" ==> c3
     // "¼" ==> bc
     bytes[] windows1252Bytes = input.getBytes(cp1252);
    
     // but in utf-8, c3 bc is "ü"
     String fixed = new String(windows1252Bytes, utf8);
    
     System.out.println(input);
     System.out.println(fixed);
    
    上述编码固定码可以正常工作,但对以下字符无效:

    (假设仅使用Windows 1252中的1字节字符):

    它适用于某些字符,例如:

    Þ       c3 9e           |       Þ      c3 9e           Þ
    ß       c3 9f           |       ß      c3 9f           ß
    à       c3 a0           |       à      c3 a0           à
    á       c3 a1           |       á      c3 a1           á
    â       c3 a2           |       â      c3 a2           â
    ã       c3 a3           |       ã      c3 a3           ã
    ä       c3 a4           |       ä      c3 a4           ä
    å       c3 a5           |       Ã¥      c3 a5           å
    æ       c3 a6           |       æ      c3 a6           æ
    ç       c3 a7           |       ç      c3 a7           ç
    

    注意-我最初认为这与你的问题有关(我自己也在做同样的事情,我想我会分享我学到的东西),但我的问题似乎略有不同。也许这会帮助其他人。

    我现在明白了这个问题。对不起,这就像在编码无效UTF-8字节时出现溢出问题[]这会导致数据丢失。谢谢你的教训。那� 是具有三个字节0xEF 0xBF 0xBD的Unicode替换字符。
     // we start with this garbage, two characters we don't want!
     String input = "ü";
    
     final Charset cp1252 = Charset.forName("windows-1252");
     final Charset utf8 = Charset.forName("UTF-8");
    
     // lets convert it to bytes in windows-1252:
     // this gives you 2 bytes: c3 bc
     // "Ã" ==> c3
     // "¼" ==> bc
     bytes[] windows1252Bytes = input.getBytes(cp1252);
    
     // but in utf-8, c3 bc is "ü"
     String fixed = new String(windows1252Bytes, utf8);
    
     System.out.println(input);
     System.out.println(fixed);
    
    char    utf-8 bytes     |   string decoded as cp1252 -->   as cp1252 bytes 
    ”       e2 80 9d        |       â€�                        e2 80 3f
    Á       c3 81           |       Ã�                         c3 3f
    Í       c3 8d           |       Ã�                         c3 3f
    Ï       c3 8f           |       Ã�                         c3 3f
    Р      c3 90           |       �                         c3 3f
    Ý       c3 9d           |       Ã�                         c3 3f
    
    Þ       c3 9e           |       Þ      c3 9e           Þ
    ß       c3 9f           |       ß      c3 9f           ß
    à       c3 a0           |       à      c3 a0           à
    á       c3 a1           |       á      c3 a1           á
    â       c3 a2           |       â      c3 a2           â
    ã       c3 a3           |       ã      c3 a3           ã
    ä       c3 a4           |       ä      c3 a4           ä
    å       c3 a5           |       Ã¥      c3 a5           å
    æ       c3 a6           |       æ      c3 a6           æ
    ç       c3 a7           |       ç      c3 a7           ç