处理Java字符串中的Unicode代理值

请考虑以下代码
byte aBytes[] = { (byte)0xff,0x01,(byte)0xd9,(byte)0x65,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06,(byte)0x07,(byte)0x17,(byte)0x33,(byte)0x74,(byte)0x6f,1,2,3,4,5,0 };
String sCompressedBytes = new String(aBytes,"UTF-16");
for (int i=0; i<sCompressedBytes.length; i++) {
    System.out.println(Integer.toHexString(sCompressedBytes.codePointAt(i)));
}

获取以下不正确的输出

ff01,fffd,506,717,3374,6f00,102,304,500.

但是,如果输入数据中的0xd9更改为0x9d,则可以获得以下正确的输出

ff01,9d65,500.

我意识到功能是因为字节0xd9是高代数Unicode标记.

问题:有没有办法在Java Unicode字符串中提供,识别和提取代理字节(0xd800到0xdfff)?
谢谢

解决方法

Is there a way to Feed,identify and extract surrogate bytes (0xd800 to 0xdfff) in a Java Unicode string?

只是因为没有人提到它,我会指出,Character课程包括使用代理对的方法.例如. isHighSurrogate(char),codePointAt(CharSequence,int)toChars(int).我意识到这是除了说明的问题之外.

new String(aBytes,"UTF-16");

这是一个将转换输入数据的解码操作.我很确定它是不合法的,因为所选的解码操作要求输入以0xfe 0xff或0xff 0xfe(byte order mark)开头.另外,由于UTF-16是variable width encoding,因此不是每个可能的字节值都能正确解码.

如果您想要将任意字节对称转换为String并返回,则最好使用8位单字节编码,因为每个字节值都是有效字符:

Charset iso8859_15 = Charset.forName("ISO-8859-15");
byte[] data = new byte[256];
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
  data[i - Byte.MIN_VALUE] = (byte) i;
}
String asstring = new String(data,iso8859_15);
byte[] encoded = asstring.getBytes(iso8859_15);
System.out.println(Arrays.equals(data,encoded));

注意:字符数将等于字节数(数据大小加倍);所得到的字符串不一定是可打印的(包含它可能是bunch of control characters).

我是with Jon,尽管把任意字节序列放入Java字符串几乎总是一个坏主意.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...