Java Unicode字节解析

4
我正在读取一个文件中的数据,作为一串字节流。我刚刚遇到了一些Unicode字符串,不确定如何最好地处理它们。
每个字符都使用两个字节,只有第一个似乎包含实际数据,例如字符串“trust”存储在文件中的方式是:
0x74 0x00(t) 0x72 0x00(r) ...and so on

通常我会使用正则表达式将零替换为空,从而移除空格。但是,文件中单词之间的空格是使用0x00 0x00实现的,所以尝试简单地进行字符串“replaceAll”可能会出现一些问题。
我尝试过调整字符串编码集,例如“ISO-8859-1”和“UTF-8/16”,但每次最终都会留下空格。
我创建了一个简单的正则表达式来移除双零十六进制值,即:
new String(bytes).replaceAll("[\\00]{2,},"");

但是这显然只适用于双零,我真的想用空格替换单个零,并用实际的ASCII/Unicode空格字符替换双零。
我记得Java字符串格式设置中有一种处理这种情况的方法,但我可能错了。那么我应该创建一个正则表达式来去除零,还是Java实际上提供了进行此操作的机制?
谢谢
2个回答

7
那就是"UTF-16LE"编码。在UTF-16中,0x00 0x00实际上编码了NUL字符,因此你会得到这个结果。
该编码可以使用每个字符2或4字节编码约一百万个不同的字符。前256个字符使用第二个字节0x00进行编码,如果文本仅包含这些字符,则可能被视为无用,但对于其余字符而言,这是必需的。例如,欧元货币符号€将显示为0xAC 0x20。

啊,是的,我找不到它。这回答了我的问题并解决了它。非常感谢您的快速回复,我会尽快点击接受。谢谢Esailija! - Tony

5

我正在以字节流的形式从文件中读取一些数据,然后遇到了一些Unicode字符串,我不确定如何最好地处理它们。

使用适当的字符集将它们转换为字符串,这种情况下是UTF-16LE(小端UTF-16,先是低位字节,然后是高位字节)。

String str = new String(bytes, "UTF-16LE");

谢谢Ian,这正是我所做的。顺便问一下,有什么最好的方法来识别正在使用的Unicode字符集类型? - Tony
2
@Tony 通常编码不是被识别出来的,而是明确告知的。比如,如果你从一个HTTP服务器获取文件,服务器可能会发送包含编码信息的HTTP头。没有这些信息,自动检测编码是不可靠的。手动地,我们可以尝试猜测最佳编码并查看文本是否正确显示。http://en.wikipedia.org/wiki/Charset_detection - Esailija
2
@Tony 实际上没有“最佳方法”,除非数据以字节顺序标记开头 - 如果前两个字节是 FE FF,则为大端 UTF-16,FF FE 则为小端 UTF-16,EF BB BF 则为 UTF-8。但如果你正在读取一个二进制格式,那么格式规范应该告诉你期望的编码(包括字节顺序)。 - Ian Roberts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接