除去BOM我在byte[] byteArray
xml
数据可以或那下跪包含BOM。 C#中有没有标准的方法来删除它的BOM?如果不是,那么处理包括所有类型编码在内的所有情况的最好方法是什么?如何从字节数组
其实,我在固定的代码中的错误,我不希望改变很多代码。所以如果有人可以给我代码删除BOM会更好。
我知道我可以像找出60
这是'<'的ASCII值并忽略字节,但我不想这样做。
除去BOM我在byte[] byteArray
xml
数据可以或那下跪包含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,不必关心解析和所有。我也更新了这个问题 – 2013-03-18 12:39:03
@RaviGupta我看,你知道编码吗? – 2013-03-18 12:42:53
这将是更好的,如果逻辑编码自由。 – 2013-03-18 12:46:50
你必须识别字节字节数组开头的顺序标记。有几种不同的组合,如http://www.unicode.org/faq/utf_bom.html#bom1所述。
只需创建始于字节数组的开头和查找这些序列的小状态机。
我不知道你的阵列是如何使用或者我真的不能说什么其他的,你与它使用的参数,所以你怎么想“删除”序列。您的选择似乎是:
start
和count
参数,你可以改变这些以反映阵列的起点(超出BOM)。count
参数(数组的Length
属性除外),则可以移动数组中的数据以覆盖BOM,并相应地调整count
。start
或count
参数,那么您需要创建一个与旧数组大小相同的新数组减去BOM,然后将数据复制到新数组中。要“移除”序列,您可能需要标识标记(如果存在),然后将其余字节复制到新的字节数组中。或者,如果你保持字符数(大于数组的Length
财产等)
你可以做这样的事情,而从流中读取跳过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();
}
}
数据既可以是UTF-8(具有或不具有字节顺序标记)或UTF16(有或全无BOM;小端或大端)? – 2013-03-18 12:04:39
我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“吗?](http:// meta。stackexchange.com/questions/19190/)“,其中的共识是”不,他们不应该“。 – 2013-03-18 13:07:08