11000000 10000000
根据Javadoc的说明,这两个字符实际上都不是00。这是一个绕过不能轻易更改的东西的技巧。还要注意,这是有效的UTF-8,并且可以正确解码为00。没有“嵌入的空字符”意味着原始数据不包含单个 0x00
(NULL)字节。
\u0000
被编码为(二进制) 11000000 10000000
,(十六进制)0xC080
。
这不是Java的普遍差异,只存在于DataInput/OutputStream
中。如果字符串数据是使用DataOutputStream
写入的,则只需使用DataInputStream
读取即可。
如果您需要将字符串数据写入文件,不要使用DataOutputStream
,而应该使用Writer
,它适用于字符流。
这仅适用于DataOutputStream的writeUTF
方法,而不适用于普通转换流(如OutputStreamWriter等)。
这意味着,如果您有一个字符串"\u0000"
,它将被编码为0xC0 0x80
,而不是简单的0x00
。
另外,在另一方面,这个序列0xB0 0x80
,在正常的UTF-8字符串中永远不会出现,代表一个空字符。
此外,您链接的文档似乎是Unicode仍然是16位字符集的时候 - 现在它也允许超过0xFFFF的字符,每个字符将由两个Java char
值表示(以UTF-16格式,代理对),并且如果我计算正确,需要4个字节的UTF-8。不过我不确定这里的实现 - 它看起来像是用CESU-8格式编写的(例如,两个3字节序列,每个序列对应一个UTF-16代理,它们一起给出一个Unicode字符)。您也需要注意这一点。
getBytes("UTF-8")
或OutputStreamWriter将其转换为真正的UTF-8数据。如果使用DataOutput.writeUTF8写入了字符串,则DataInput.readUTF8()
javadoc是明确的规范。除了对NUL
的非标准处理外,它还指定字符串以无符号16位字节计数开头。
如果使用ObjectOutputStream.writeObject()
写入字符串,则序列化规范是明确的。
readUTF
在数据流上获取(真实的)Unicode字符串。 - hakreDataOutputStream
写入的数据还是由DataInputStream
读取的数据引起的? - Matt Ball