除去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