c# . net -使用StreamWriter编写56623时出现乱码

本文关键字:56623时 编写 net 使用 StreamWriter | 更新日期: 2023-09-27 18:07:10

我有一个使用UTF16的StreamWriter将字符56623写入流的问题(该问题也存在于其他编码中)。如果我从流中获取缓冲区,它包含值65533,而不是我最初写的值。当我做随机单元测试时,这个问题悄悄出现了,值6000095都没有出现。

为了说明,我有一个最小的程序来检查行为:
   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和buffer,我得到:

   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的实现有问题,所以我缺少了一些东西。

我在这里没有看到什么?

谢谢!

c# . net -使用StreamWriter编写56623时出现乱码

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

它应该是好的,如果你写它作为一个有效的代理对的一部分(即后面跟着一个低代理)-但如果你试图写它自己,这表明你有无效的数据开始。您不应该使用随机的UTF-16代码单元并期望它们是有效的Unicode代码点。如果您显式地排除U+D800到U+DFFF,则可能是可以的,但即使这样,您也会得到像BOM这样的奇怪字符,这些字符不应该出现在正常文本中。