【问题标题】:C# .NET - Garbled character when writing 56623 with StreamWriterC# .NET - 使用 StreamWriter 写入 56623 时出现乱码
【发布时间】:2014-07-27 18:56:37
【问题描述】:

我在使用 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 和缓冲区,我得到:

   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 character-encoding char streamwriter


    【解决方案1】:

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

    如果您将它作为有效代理对的一部分(即后跟低代理)编写应该没问题 - 但如果您尝试自己编写它,则表明您有无效数据开始和。您不应该采用随机的 UTF-16 代码单元并期望它们是有效的 Unicode 代码点。如果您明确将 U+D800 排除在 U+DFFF (含)范围内,可能没问题,但即便如此,您也会有像 BOM 这样的奇怪字符,它们不应该出现在普通文本中。

    【讨论】:

    • 谢谢!因此,这显然是我的测试选择的一个问题。关于如何生成有效的随机 Unicode 字符(和字符串),您是否有任何提示,或者在我的测试中跳过随机化(成本/价值)更好?
    • @Vectovox:我会考虑选择合理字符的范围——您可能想使用unicode.org/charts 来考虑什么范围是合理的。
    猜你喜欢
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多