我在使用UTF16中的StreamWriter将字符 56623 写入流时遇到问题(此问题也存在于其他编码中)。如果我从流中获取缓冲区,它包含值 65533 而不是我最初编写的值。在进行随机单元测试时,这个问题在我身上悄然发生,并且它不会出现值 60000 或 95 。
为了说明,我有一个检查行为的最小程序:
char value = (char)56623;
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream, Encoding.Unicode);
writer.Write(value);
writer.Close();
var byteArray = BitConverter.GetBytes(value); // Reference bytes
var buffer = writer.GetBuffer();
通过读取byteArray和缓冲区我得到:
byteArray = [221,47] = 11011101 00101111 = 56623
buffer = [255,254,253,255,...] = BOM 11111101 11111111 ... = BOM 65533
因此,写入值 65533 与原 56623 明显不等于。但是,尝试使用值 60000 时,会写入正确的值:
byteArray = [96,234] = 01100000 11101010 = 60000
buffer = [255,254,96,234,...] = BOM 01100000 11101010 ... = BOM 60000
我无法理解为什么会出现这种情况,但我不愿意认为StreamWriter的实现存在问题,因此存在我缺少的内容。
我在这里看不到什么?
谢谢!
答案 0 :(得分:2)
问题是56623是U + DD2F - 这是高代理 UTF-16代码单元。它本身无效 - 它仅作为代理对的一部分有效,用于编码基本多语言平面中不存在的代码点。
如果你把它写成有效代理人对的一部分(即后面跟一个低代理人),应该没问题 - 但是如果你自己编写它,那表明你已经得到了无效的数据开始。您不应该使用随机UTF-16代码单元并期望它们是有效的Unicode代码点。如果你明确地将U + D800排除在U + DFFF之外,可能可以,但即使这样,你也会得到奇怪的字符,就像在正常文本中不应该出现的BOM一样。 / p>