猿问

如何在 Java 中对字节数组中的补充 unicode 字符进行编码?

我正在使用 anInputStream从 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。-3 -1但是,无法识别“Ü”字符,我认为这是由于 Java 尝试(但未能)编码的 UTF-16 值造成的。我知道在 C# 中,“Ü”由 表示DC-00,但我不明白为什么-3 -1在 Java 中会变成这样。任何帮助将不胜感激。


MMMHUHU
浏览 131回答 1
1回答

GCT1015

“Û”字符未在您的源代码中编码 - 到达接收器端“-3,-1”的序列是-替换字符0xfffd的 UTF 16 LE 编码。如果没有看到服务器端代码,很难判断发生了什么,但它很糟糕。Utf-16 可以处理像“Ü”这样的字符而不会妨碍它。实际上,它甚至不在前 256 个 unicode 代码点之外,更不用说在 Base Multilingual Plane 之外了。(这是一个在许多西方语言中很常见的字符,甚至是拉丁字符,它怎么会脱离为世界上所有语言设计的字符的平面?)发生的事情是,从您的文本到用于电汇的 utf-16 的代码路径在某些时候被明确指示为任何不仅仅是 ASCII 的字符设置替换字符(旧版 unicode 代码点 0x20 -0x7f,其中仅包括无重音的拉丁字符)。明确地说,换句话说:数据在服务器端被破坏,所有非 ASCII 适合的字符都可能被压缩为“替换字符”。对客户端代码进行再多的改动也无法解决这个问题。
随时随地看视频慕课网APP

相关分类

Java
我要回答