2013-02-07 57 views
3

我只是在从文件中读取一些数据作为字节流的过程中,我刚刚遇到一些unicode字符串,我不知道如何处理。Java unicode字节解析

每个字符都使用两个字节,仅在第一个似乎到包含实际数据,因此,例如字符串“信任”被存储在文件中:

0x74 0x00(t) 0x72 0x00(r) ...and so on 

一般情况下我只用一个正则表达式用零代替零,因此删除空白。但是,文件内的单词之间的空格是通过使用0x00 0x00来实现的,所以试图做一个简单的String'replaceAll'就会让它变得有点麻烦。

我已经尝试过使用字符串编码集,比如'ISO-8859-1'和'UTF-8/16',但每次我都要用空格结束。

我没有创建一个简单的正则表达式来去除双零个十六进制值,这就是:

new String(bytes).replaceAll("[\\00]{2,},""); 

但这显然只适用于双零,我真的很想来取代单一的零一无所有,以及具有实际的ASCII/Unicode空格字符的双零。

我可以发誓,其中一个Java字符串格式设置处理这种事情,但我可能是错的。那么我是否应该创建一个正则表达式来去除零,或者Java是否提供了实现它的机制?

谢谢

回答

6

那就是"UTF-16LE"0x00 0x00实际上是以UTF-16编码NUL字符,所以这就是你会得到的。

该编码可以编码大约一百万个不同的字符,每个字符使用2或4个字节。前256个字符用第二个字节0x00编码,如果文本只包含那些可能被视为无用的字符,但是其他字符需要。例如,欧元货币符号将显示为0xAC 0x20

+0

啊,是的,就是这样,我无法找到这个。这回答了我的问题并修复了它。非常感谢您的快速回复,我会尽快点击接受。感谢Esailija! – Tony

3

我只是在从文件中读取一些数据作为字节流的过程中,我刚刚遇到一些unicode字符串,我不知道如何处理。

它们转换为使用适当的字符集的字符串,在这种情况下UTF-16LE(little-endian的UTF-16,与低位字节第一其次高位字节)

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

谢谢伊恩,那正是我所做的。出于兴趣,识别正在使用的unicode字符集类型的最佳方式是什么? – Tony

+2

@Tony通常的编码没有被识别,但明确告诉。就像如果您从http服务器获取文件一样,服务器可能会向您发送包含编码的http标头。没有这些信息,自动检测编码是不可靠的。手动可以做一个最好的猜测,看看文本是否正确。 HTTP://en.wikipedia。org/wiki/Charset_detection – Esailija

+2

@Tony除非数据以字节顺序标记开头 - 如果前两个字节是FE FF,那么它是big-endian UTF-16,FF FE则不是真正的“最佳方式” - 印度的UTF-16,EF BB BF的UTF-8。但是,如果你正在阅读二进制格式,那么格式规范应该告诉你什么编码(包括字节顺序)的期望。 –