2013-03-18 4 views
4

xml의 데이터가 byte[] byteArray인데 BOM을 포함하거나 포함하지 않을 수 있습니다. C#에서 BOM을 제거하는 표준 방법이 있습니까? 그렇지 않다면 모든 인코딩 유형을 포함하여 모든 경우를 처리하는 최선의 방법은 무엇입니까?바이트 배열에서 BOM을 제거하는 방법

사실, 코드의 버그를 수정하고 코드의 많은 부분을 변경하고 싶지 않습니다. 따라서 BOM을 제거하는 코드를 누군가가 나에게 줄 수 있다면 더 좋을 것입니다.

나는 <의 ASCII 값인 60을 발견하고 그 전에 바이트를 무시하지만 그렇게하고 싶지는 않다는 것을 알고있다.

+0

에서 인코딩 유형에 대한 정보를 가지고 빅 엔디안)? –

+0

제목을 편집했습니다. "[제목에"태그 "가 포함되어야합니까?] (http : // meta.stackexchange.com/questions/19190/) ", 공감대는"아니오, 그들은해서는 안됩니다. " –

답변

5

모든 C# XML 구문 분석기가 자동으로 BOM을 처리합니다. XDocument을 사용하는 것이 좋습니다 - 제 생각에는 XML 데이터의 가장 깨끗한 추상화를 제공합니다. 당신이하여 XDocument이 있으면

using (var stream = new memoryStream(bytes)) 
{ 
    var document = XDocument.Load(stream); 
    ... 
} 

당신이 다음 BOM없이 바이트를 생략하는 데 사용할 수 있습니다 : 예제로하여 XDocument를 사용

using (var stream = new MemoryStream()) 
using (var writer = XmlWriter.Create(stream)) 
{ 
    writer.Settings.Encoding = new UTF8Encoding(false); 
    document.WriteTo(writer); 
    var bytesWithoutBOM = stream.ToArray(); 
} 
+0

실제로 BOM 만 제거하고 파싱 및 모든 것에 대해 신경 쓸 필요가 없습니다. 질문도 업데이트했습니다. . –

+0

@RaviGupta 알겠습니다. 인코딩을 알고 있습니까? –

+0

로직이 자유롭게 인코딩되면 더 좋을 것입니다. –

0

당신은 바이트를 식별해야합니다 바이트 배열의 선두에 순서 마크. http://www.unicode.org/faq/utf_bom.html#bom1에 설명 된대로 여러 가지 조합이 있습니다.

바이트 배열의 시작 부분에서 시작하는 작은 상태 머신을 만들고 해당 시퀀스를 찾습니다.

배열의 사용 방법이나 다른 매개 변수를 사용하는 방법을 모르므로 시퀀스를 "제거하는 방법"을 실제로 말할 수는 없습니다. 옵션은 것으로 나타납니다 : 당신이 startcount 매개 변수가있는 경우

  1. , 당신은 단지 (BOM을 넘어) 배열의 시작점을 반영하기 위해 사람들을 변경할 수 있습니다.
  2. count 매개 변수 (배열의 Length 속성 제외)가있는 경우 배열의 데이터를 이동하여 BOM을 덮어 쓰고 그에 따라 count을 조정할 수 있습니다.
  3. start 또는 count 매개 변수가없는 경우 이전 배열 크기에서 BOM을 뺀 새 배열을 만들고 새 배열에 데이터를 복사해야합니다.

시퀀스를 "제거하려면"표시가있는 경우이를 식별 한 다음 나머지 바이트를 새 바이트 배열에 복사하는 것이 좋습니다. 또는 문자 수를 유지하는 경우 (배열의 Length 속성 제외)

0

스트림에서 읽는 동안 BOM 바이트를 건너 뛸 수 있습니다. 추가 인코딩을 포함하도록 Bom.cs를 확장해야하지만 afaik UTF 만 BOM을 사용하는 인코딩입니다 ... (가장 가능성 있음) 잘못 생각할 수도 있습니다. 리틀 엔디안 또는,

나는 데이터 (또는 바이트 순서 마크없이)이나 또는 BOM withour UTF16 (중 UTF-8이 될 수 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(); 
     } 
    } 
관련 문제