为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

MMMHUHU 2023-05-24 15:27:45
我正在使用 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 中会变成这样。任何帮助将不胜感激。
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

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

如果没有看到服务器端代码,很难判断发生了什么,但它很糟糕。Utf-16 可以处理像“Ü”这样的字符而不会妨碍它。实际上,它甚至不在前 256 个 unicode 代码点之外,更不用说在 Base Multilingual Plane 之外了。(这是一个在许多西方语言中很常见的字符,甚至是拉丁字符,它怎么会脱离为世界上所有语言设计的字符的平面?)

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

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


查看完整回答
反对 回复 2023-05-24
  • 1 回答
  • 0 关注
  • 130 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信