我正在尝试将java字符串序列化为字节数组,然后再将数组反序列化为字符串。在我测试了unicode字符\ude4e
之前,似乎工作正常。由于某种原因,原始字符串"\ud34e"
不等于反序列化的字符串。
这是序列化代码(其中encoding = Charset.forName( "UTF-16BE" )
和str = "\ud34e"
)
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer temp = new OutputStreamWriter( out, encoding );
temp.write( str );
temp.close();
byte[] bytes = out.toByteArray();
String deserialized = new String( bytes, encoding );
那么我做错了什么? 谢谢!
答案 0 :(得分:6)
DE4E是代理对的1/2。它本身就是无效的。它将被转换为?或由OutputStreamWriter丢弃。如果使用java.nio类,则可以看到错误。
答案 1 :(得分:3)
当我在在线Unicode charts上查找代码de4e
时,它表示此代码位于低代理图表中。它本身不是一个字符,而是一个在UTF-16中使用的特殊代码(根据那里的文档)。
Unicode并不像单个字符映射到单个代码点那么简单 - 有很多怪癖和事物,不同的代码点和字节序列可能引用相同的字符。
当序列化和反序列化时,某些代码点很可能产生不同但等效的代码点。
答案 2 :(得分:1)
public static void main(String[] args) throws IOException {
Charset encoding = Charset.forName( "UTF-16BE" );
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer temp = new OutputStreamWriter( out, encoding );
String str = "\ud34e";
temp.write( str );
temp.close();
byte[] bytes = out.toByteArray();
String deserialized = new String( bytes, encoding );
System.out.println("'" + str + "' / '" + deserialized + "' / " + (str.equals(deserialized)));
}
对我来说,输出是:
'?' / '?' / true
即。他们是平等的......
我正在使用: java版“1.6.0_24” Java(TM)SE运行时环境(版本1.6.0_24-b07) Java HotSpot(TM)64位服务器VM(版本19.1-b02,混合模式)
答案 3 :(得分:0)
虽然它不是一个有效的字符,但@Ant显示编码解码返回原始字符。这可能是因为UTF-16是一种非常简单的直接编码,与Java的16位字符表示相符。
如果我们尝试使用UTF-8,编码应该会产生致命错误。 UTF-8无法编码代理对的一半。