如何在字符串比较中忽略UTF-8字节顺序标记?
我在使用Visual Studio 2010比较C#4.0中的unit testing中的字符串时遇到问题。同样的测试用例在Visual Studio 2008中正常工作(使用C#3.5)。
这是相关的代码段:
byte[] rawData = GetData(); string data = Encoding.UTF8.GetString(rawData); Assert.AreEqual("Constant", data, false, CultureInfo.InvariantCulture);
在调试此测试时, data
字符串肉眼看来包含与文字完全相同的字符串。 当我调用data.ToCharArray()
,我注意到字符串data
的第一个字节是值65279
,它是UTF-8字节顺序标记。 我不明白的是为什么Encoding.UTF8.GetString()
保持这个字节。
如何让Encoding.UTF8.GetString()
不将字节顺序标记放在结果字符串中?
更新:问题是GetData()
从磁盘读取文件,使用FileStream.readbytes()
从文件中读取数据。 我通过使用StreamReader
并使用Encoding.UTF8.GetBytes()
将字符串转换为字节来纠正这个问题,这应该是它本来应该做的! 谢谢你的帮助。
好吧,我认为这是因为原始二进制数据包括BOM。 您可以在解码后自己删除BOM,如果您不想要它 – 但您应该考虑字节数组是否应该考虑开始使用BOM。
编辑:或者,您可以使用StreamReader
执行解码。 这是一个示例,显示使用Encoding.GetString
将相同的字节数组转换为两个字符或通过StreamReader
转换为一个字符:
using System; using System.IO; using System.Text; class Test { static void Main() { byte[] withBom = { 0xef, 0xbb, 0xbf, 0x41 }; string viaEncoding = Encoding.UTF8.GetString(withBom); Console.WriteLine(viaEncoding.Length); string viaStreamReader; using (StreamReader reader = new StreamReader (new MemoryStream(withBom), Encoding.UTF8)) { viaStreamReader = reader.ReadToEnd(); } Console.WriteLine(viaStreamReader.Length); } }
有一种比创建StreamReader和MemoryStream更有效的方法:
1)如果您知道总有BOM
string viaEncoding = Encoding.UTF8.GetString(withBom, 3, withBom.Length - 3);
2)如果您不知道,请检查:
string viaEncoding; if (withBom.Length >= 3 && withBom[0] == 0xEF && withBom[1] == 0xBB && withBom[2] == 0xBF) viaEncoding = Encoding.UTF8.GetString(withBom, 3, withBom.Length - 3); else viaEncoding = Encoding.UTF8.GetString(withBom);
我相信如果你修剪()解码的字符串,删除额外的字符