Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.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 1.6 Windows-1252编码在3个字符上失败_Java_Codepages_Windows 1252 - Fatal编程技术网

Java 1.6 Windows-1252编码在3个字符上失败

Java 1.6 Windows-1252编码在3个字符上失败,java,codepages,windows-1252,Java,Codepages,Windows 1252,编辑:我确信这个问题有点不理智。感谢那些回应的人。我可以发布更具体的后续问题。 今天,我投资了一些编码问题,并编写了这个单元测试来分离一个基本复制案例: int badCount = 0; for (int i = 1; i < 255; i++) { String str = "Hi " + new String(new char[] { (char) i }); String toLatin1 = new String(str.getBytes("UTF-8"),

编辑:我确信这个问题有点不理智。感谢那些回应的人。我可以发布更具体的后续问题。

今天,我投资了一些编码问题,并编写了这个单元测试来分离一个基本复制案例:

int badCount = 0;
for (int i = 1; i < 255; i++) {
    String str = "Hi " + new String(new char[] { (char) i });

    String toLatin1  = new String(str.getBytes("UTF-8"), "latin1");
    assertEquals(str, new String(toLatin1.getBytes("latin1"), "UTF-8"));

    String toWin1252 = new String(str.getBytes("UTF-8"), "Windows-1252");
    String fromWin1252 = new String(toWin1252.getBytes("Windows-1252"), "UTF-8");

    if (!str.equals(fromWin1252)) {
        System.out.println("Can't encode: " + i + " - " + str + 
                           " - encodes as: " + fromWin1252);
        badCount++;
    }
}

System.out.println("Bad count: " + badCount);
int badCount=0;
对于(int i=1;i<255;i++){
String str=“Hi”+新字符串(新字符[]{(字符)i});
字符串toLatin1=新字符串(str.getBytes(“UTF-8”),“latin1”);
assertEquals(str,新字符串(toLatin1.getBytes(“latin1”),“UTF-8”);
字符串toWin1252=新字符串(str.getBytes(“UTF-8”),“Windows-1252”);
String fromWin1252=新字符串(toWin1252.getBytes(“Windows-1252”),“UTF-8”);
如果(!str.equals(fromWin1252)){
System.out.println(“无法编码:”+i+“-”+str+
“-编码为:”+fromWin1252);
坏计数++;
}
}
System.out.println(“坏计数:+badCount”);
输出:

Can't encode: 129 - Hi ? - encodes as: Hi ?? Can't encode: 141 - Hi ? - encodes as: Hi ?? Can't encode: 143 - Hi ? - encodes as: Hi ?? Can't encode: 144 - Hi ? - encodes as: Hi ?? Can't encode: 157 - Hi ? - encodes as: Hi ?? Can't encode: 193 - Hi Á - encodes as: Hi ?? Can't encode: 205 - Hi Í - encodes as: Hi ?? Can't encode: 207 - Hi Ï - encodes as: Hi ?? Can't encode: 208 - Hi ? - encodes as: Hi ?? Can't encode: 221 - Hi ? - encodes as: Hi ?? Bad count: 10 无法编码:129-嗨编码为:嗨?? 无法编码:141-嗨编码为:嗨?? 无法编码:143-嗨编码为:嗨?? 无法编码:144-嗨编码为:嗨?? 无法编码:157-嗨?-编码为:嗨?? 无法编码:193-HiÁ-编码为:Hi?? 无法编码:205-HiÍ-编码为:Hi?? 无法编码:207-HiÏ-编码为:Hi?? 无法编码:208-嗨编码为:嗨?? 无法编码:221-嗨编码为:嗨?? 错误计数:10 Mac OS 10.6.2上的JDK 1.6.0_07

我的观察:

Latin1对所有254个字符进行对称编码。Windows-1252没有。这三个可打印字符(193205207)在Latin1和Windows-1252中是相同的代码,所以我不希望出现任何问题

有人能解释这种行为吗?这是JDK错误吗


--James

在我看来,测试程序有很大的缺陷,因为它在没有语义的字符串之间进行有效的无用转换

如果要检查所有字节值是否都是给定编码的有效值,则类似于以下内容:

public static void tryEncoding(final String encoding) throws UnsupportedEncodingException {
    int badCount = 0;
    for (int i = 1; i < 255; i++) {
        byte[] bytes = new byte[] { (byte) i };

        String toString = new String(bytes, encoding);
        byte[] fromString = toString.getBytes(encoding);

        if (!Arrays.equals(bytes, fromString)) {
            System.out.println("Can't encode: " + i + " - in: " + Arrays.toString(bytes) + "/ out: "
                    + Arrays.toString(fromString) + " - result: " + toString);
            badCount++;
        }
    }

    System.out.println("Bad count: " + badCount);
}
这说明
Windows-1252
不接受字节值129、1441、143、144和157作为有效值。(注意:这里我说的是无符号字节值。上面的代码显示了-127,-115,…因为Java只知道无符号字节)

似乎通过陈述以下内容来验证这一观察结果:

根据微软和Unicode联盟网站上的信息,位置81、8D、8F、90和9D未使用

你的代码所做的(
String->byte[]->String
,两次)几乎与代码转换相反,而且毫无意义(它实际上保证会丢失数据)。转码是指
字节[]->字符串->字节[]

public byte[] transcode(byte[] input, String inputEnc, String targetEnc)
{
    return new String(input, inputEnc).getBytes(targetEnc);
}

当然,当输入包含目标编码不支持的字符时,它将丢失数据。

您发布的代码没有任何意义(从字符串中获取UTF-8编码的数据,并将其解释为拉丁文1)。因此,很难理解您试图做的事情。我有一些数据编码为UTF-8,需要转码到Windows-1252。在我的制作系统中,我注意到这在193字符上失败了,所以我写了这个基本的复制案例,让我惊讶的是,这10个字符在Windows-1252和UTF-8之间没有对称编码。请注意,所有254个字符都可以在UTF-8和Latin1之间编码。因此我感到惊讶和困惑。这有用吗?你说的“转码”到底是什么意思?您想要表示相同标志符号的Windows-1252编码字节吗?如果是这样的话,那么您必须意识到这在所有情况下都是不可能的,因为UTF-8可以表示所有Unicode字符,而Windows-1252显然不能。我的问题没用。我可能会发布一个新的,但我想在发布之前挖掘更多,以便下次可以问一个更聪明的问题。Joachim,谢谢你的测试。请注意,上面的输出中没有字符193、205和207。为什么它们在Windows-1252中编码不正确,但在拉丁语1中编码正确?该代码映射到两个代码页中的同一个字符。@James:“为什么它们在Windows-1252中编码不正确”是错误的问题。字符U+00C1(代码点193)在UTF-8中表示为0xC3 0x81。当您尝试将这些字节解释为Windows-1252时,您会注意到0x81不是Windows-1252的有效值,将被替换为替换字符。这是有道理的。非常感谢。我需要提出一个新的问题,因为这一个问题混淆了这个问题。对不起,我不知道这和我的例子有什么不同。你能举个例子来说明这实际上是编码之间的代码转换吗?我的测试表明代码和我的代码完全一样。如果您有一个UTF-8编码的字节数组,并传入“Windows-1252”作为目标编码,您将无法返回正确编码的字符串——您将得到乱码。请参阅我的Charset transcode()实现。“我想这就是我们所追求的。”James看来您对Java字符串的含义有一些误解。它们是解码的字符(内部使用UTF-16,但这与此无关)。不能解码字符串。字节数组被解码为字符串,字符串被编码为字节数组。代码转换以字节数组开始和结束,因为字节数组是抽象字符串的具体的、依赖于编码的表示形式。谢谢。我正在维护一个应用程序,其中字符串是在不正确的上游创建的(在某些DAO代码中,由于MySQL中的数据存储不正确)。原始字节为UTF-8,但字符串是使用Windows-1252创建的。我的目标是获取一个Java字符串,这是我目前所拥有的全部内容,并以某种方式对其进行转换,使其不至于胡言乱语。我意识到我并没有解决根本原因等问题,但在维修工程中,这有时是我们的困境。Jochaim的回答是0x81未在Wind中定义
public byte[] transcode(byte[] input, String inputEnc, String targetEnc)
{
    return new String(input, inputEnc).getBytes(targetEnc);
}