我在xml
中有byte[] byteArray
数据,可能包含或不包含BOM。 C#中是否有任何标准方法可以从中删除BOM?如果没有,那么处理包括所有类型编码在内的所有情况的最佳方法是什么呢?
实际上,我正在修复代码中的错误,我不想更改大部分代码。所以如果有人能给我删除BOM的代码会更好。
我知道我能做的就是找出60
这是'ASCII值'
所有C#XML解析器都会自动为您处理BOM。我建议使用XDocument - 在我看来它提供了最干净的XML数据抽象。
以XDocument为例:
using (var stream = new memoryStream(bytes))
{
var document = XDocument.Load(stream);
...
}
一旦有了XDocument,就可以使用它来省略没有BOM的字节:
using (var stream = new MemoryStream())
using (var writer = XmlWriter.Create(stream))
{
writer.Settings.Encoding = new UTF8Encoding(false);
document.WriteTo(writer);
var bytesWithoutBOM = stream.ToArray();
}
您可以执行类似这样的操作,以便在从流中读取时跳过BOM字节。您需要扩展Bom.cs以包含进一步的编码,但是afaik UTF是使用BOM的唯一编码...虽然可能(很可能)是错误的。
我从here获得了编码类型的信息
using (var stream = File.OpenRead("path_to_file"))
{
stream.Position = Bom.GetCursor(stream);
}
public static class Bom
{
public static int GetCursor(Stream stream)
{
// UTF-32, big-endian
if (IsMatch(stream, new byte[] {0x00, 0x00, 0xFE, 0xFF}))
return 4;
// UTF-32, little-endian
if (IsMatch(stream, new byte[] { 0xFF, 0xFE, 0x00, 0x00 }))
return 4;
// UTF-16, big-endian
if (IsMatch(stream, new byte[] { 0xFE, 0xFF }))
return 2;
// UTF-16, little-endian
if (IsMatch(stream, new byte[] { 0xFF, 0xFE }))
return 2;
// UTF-8
if (IsMatch(stream, new byte[] { 0xEF, 0xBB, 0xBF }))
return 3;
return 0;
}
private static bool IsMatch(Stream stream, byte[] match)
{
stream.Position = 0;
var buffer = new byte[match.Length];
stream.Read(buffer, 0, buffer.Length);
return !buffer.Where((t, i) => t != match[i]).Any();
}
}
您必须在字节数组的开头标识字节顺序标记。有几种不同的组合,如http://www.unicode.org/faq/utf_bom.html#bom1所述。
只需创建一个从字节数组的开头开始并查找这些序列的小状态机。
我不知道你的数组是如何使用的,或者你使用的是什么其他参数,所以我不能说你如何“删除”序列。您的选择似乎是:
start
和count
参数,你可以改变它们以反映数组的起点(超出BOM)。count
参数(除了数组的Length
属性),你可以移动数组中的数据来覆盖BOM,并相应地调整count
。start
或count
参数,那么您将需要创建一个新数组,该数组的大小与旧数组相比减去BOM,并将数据复制到新数组中。要“删除”序列,您可能需要识别标记,如果它在那里,然后将剩余的字节复制到新的字节数组。或者,如果你保持一个字符数(除了数组的Length
属性)
您不必担心BOM。
如果由于某种原因你需要使用和XmlDocument对象,这个代码可能会帮助你:
byte[] file_content = {wherever you get it};
XmlDocument xml = new XmlDocument();
xml.Load(new MemoryStream(file_content));
当我尝试使用Google Api从gmail帐户下载xml附件并且该文件具有BOM并使用Encoding.UTF8.GetString(file_content)无法“正常”工作时,它对我有用。