【问题标题】:How do I encode supplementary unicode characters from a byte array in Java?如何在 Java 中对字节数组中的补充 unicode 字符进行编码?
【发布时间】:2019-12-16 23:39:48
【问题描述】:

我正在使用InputStream 将字节从 TCP 服务器(用 C# 编写)读取到 byte[],并使用 new String(byteArray, "UTF-16LE") 将它们编码为字符串。此方法对基本多语言平面中的字符进行了很好的编码,但不处理补充字符。

我知道 C# 中的字节是无符号的,而 Java 字节是有符号的,并且补充字符可以由一个或两个 unicode 值组成。

        ByteBuffer wrapped = ByteBuffer.wrap(dataBytes);
        wrapped.order(ByteOrder.LITTLE_ENDIAN);
        short noOfSites = wrapped.getShort();

        for(int i = 0; i < noOfSites; i++){
            short siteNo = wrapped.getShort();
            short textLength = wrapped.getShort();
            byte[] textBytes = new byte[textLength];
            wrapped.get(textBytes, 0, textLength);

            for(byte bite : textBytes){
                System.out.print(bite+" ");
            } //just to see what's in the byte array

            String siteText = new String(textBytes, "UTF_16LE");
            System.out.println(siteNo + ": " + siteText);
            siteList.add(new Site(siteNo, siteText));
            publishProgress(siteNo + " - " + siteText);
        }

在本例中,dataBytes 是包含从服务器读取的字节的字节数组,noOfSites 是要从服务器读取的对象数,siteNo 是 ID,textLength 是数字包含站点名称的字节数,textBytes 是保存这些字节的数组。

当从服务器接收到单词“MÜNSTER”时,读入缓冲区的字节为: 77 0 -3 -1 78 0 83 0 84 0 69 0 82 0。 但是,“Ü”字符无法识别,我认为这归因于 Java 尝试(并且失败)编码的 -3 -1 UTF-16 值。我知道在 C# 中,“Ü”由 DC-00 表示,但我不明白为什么这在 Java 中变成 -3 -1。 任何帮助将不胜感激。

【问题讨论】:

    标签: java android unicode tcp


    【解决方案1】:

    “Û”字符未在您的源中编码 - 到达接收器端“-3,-1”的序列是 0xfffd - replacement character 的 UTF 16 LE 编码。

    如果没有看到服务器端代码,很难知道发生了什么,但它很糟糕。 utf-16 可以毫不费力地处理像“Ü”这样的字符。实际上,它甚至不在前 256 个 unicode 代码点之外,更不用说在基本多语言平面之外了。 (这是一个在许多西方语言中足够常见的字符,甚至是拉丁字符,它怎么可能超出了为世界上所有语言设计的字符的平面?)

    发生的情况是,从您的文本到用于电汇的 utf-16 的代码路径在某些时候被明确指示为任何不是仅 ASCII 的字符(旧的 unicode 代码)设置替换字符-points 0x20-0x7f,其中仅包括无重音的拉丁字符)。

    明确,换句话说:数据在服务器端被损坏,所有非 ASCII 匹配字符都可能被压缩为“替换字符”。再多的修改客户端代码也无法解决这个问题。

    【讨论】:

    • 是的,好像两边的代码太多了,我们看不到另一边。
    • 非常感谢!说实话,我什至没有看到服务器代码,这是我的大错。你所说的绝对是有道理的,因为我也得到了“Ö”字符的“-3,-1”。
    猜你喜欢
    • 2011-11-07
    • 1970-01-01
    • 2013-10-08
    • 2011-12-25
    • 2011-03-14
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多