C#.NET - 使用StreamWriter编写56623时出现乱码

时间:2014-06-06 13:23:00

标签: c# .net character-encoding char streamwriter

我在使用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的实现存在问题,因此存在我缺少的内容。

我在这里看不到什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

问题是56623是U + DD2F - 这是高代理 UTF-16代码单元。它本身无效 - 它仅作为代理对的一部分有效,用于编码基本多语言平面中不存在的代码点。

如果你把它写成有效代理人对的一部分(即后面跟一个低代理人),应该没问题 - 但是如果你自己编写它,那表明你已经得到了无效的数据开始。您不应该使用随机UTF-16代码单元并期望它们是有效的Unicode代码点。如果你明确地将U + D800排除在U + DFFF之外,可能可以,但即使这样,你也会得到奇怪的字符,就像在正常文本中不应该出现的BOM一样。 / p>