Unicode转换为字符串后,会留下前导字节顺序标记。

3
在我的.NET 3.5 C#应用程序中,我正在将Unicode编码的字节数组转换为字符串。 字节数组如下所示:
{255, 254, 85, 0, 83, 0, 69, 0}

使用 Encoding.Unicode.GetString(var),我将字节数组转换为字符串,返回结果为:

{65279 '', 85 'U', 83 'S' , 69 'E'}

领头字符65279似乎是一种零宽度不换行空格,在Unicode编码中用作字节顺序标记,其外观导致应用程序的其余部分出现问题。
目前,我使用的解决方法是 var.Trim(new char[]{'\uFEFF','\u200B'});,这个方法效果很好。
但真正的问题是,GetString不应该负责删除字节顺序标记吗?或者在转换字节数组时我做错了什么?

1
@bzlm: “Encoding.Unicode可能会返回一个UTF-16编码器”-- 实际上没有“可能”的情况。鉴于这是文档中所记录的,它最好确实如此:“用小端字节顺序的UTF-16格式的编码。”(https://msdn.microsoft.com/zh-cn/library/system.text.encoding.unicode(v=vs.110).aspx) - Peter Duniho
1
你为什么要修剪\u200B - xanatos
1个回答

2
不应该在 GetString() 中删除BOM。事实上,BOM是一个完全有效的Unicode字符(特别选择它是因为如果它出现在Unicode文件的中间位置,例如如果该文件是连接多个Unicode文件的结果,则不会影响呈现的文本),必须与byte[]中的所有其他字符一起解码。
唯一应该解释和过滤BOM的代码应该是理解数据来自某些持久存储的代码,例如StreamReader。请注意,只有当您不禁用该行为时,它才会执行此操作。 GetString() 应该做的是解释实际编码的字符并将它们转换为它们表示的文本(当然,在C#字符串内部已经以UTF16存储,因此当原始数据已经是UTF16时,此转换非常简单 :))。

但是BOM从哪里来?查看字节数组,我没有看到它的二进制表示。 - Cristiano Sousa
1
@CristianoSousa 255 254 是“BOM”,即空格。或者你是指其他什么吗? - bzlm
@CristianoSousa:正如评论者bzlm所说,它在您的原始数据中。255 == 0xff254 == 0xfe。因此,在这种小端UTF16编码中,前两个字节解析为0xfeff65279十进制。就像您在解码后看到的那样。 - Peter Duniho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接