2017-01-03 3 views
3

저는 MemoryStream (원래 zip의 xml 파일에서 나온)에서 부분 문자열을 효율적으로 가져오고 싶습니다. 현재, 전체 MemoryStream을 문자열로 읽은 다음 원하는 XML 노드의 시작 및 끝 태그를 검색합니다. 이것은 잘 작동하지만 텍스트 파일이 매우 클 수 있으므로 전체 MemoryStream을 문자열로 변환하지 않고 대신 스트림에서 직접 XML 텍스트의 원하는 섹션을 추출하십시오.전체 스트림을 문자열로 변환하지 않고 MemoryStream에서 부분 문자열 가져 오기

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 그 그것이 줄 바꿈이있을 것이다 XML이기 때문에, 아마에서는 StreamReader에서는 ReadLine를 사용하여 각 행에 태그를 검색하는 가장 좋은 것입니다 가정

string xmlText; 
using (var zip = ZipFile.Read(zipFileName)) 
{ 
    var ze = zip[zipPath]; 
    using (var ms = new MemoryStream()) 
    { 
     ze.Extract(ms); 
     ms.Position = 0; 
     using(var sr = new StreamReader(ms)) 
     { 
      xmlText = sr.ReadToEnd(); 
     } 
    } 
} 

string startTag = "<someTag>"; 
string endTag = "</someTag>"; 
int startIndex = xmlText.IndexOf(startTag, StringComparison.Ordinal); 
int endIndex = xmlText.IndexOf(endTag, startIndex, StringComparison.Ordinal) + endTag.Length - 1; 
xmlText = xmlText.Substring(startIndex, endIndex - startIndex + 1); 
+2

메모리 스트림에서 전체 파일을로드하지 않도록 'XmlReader'를 만들 수 있습니다. – juharr

+1

@juharr : 답으로 답장하십시오. 다른 방법은 왕궁 통증이 될 것이며 아마도 제대로 작동하지 않을 것입니다. – Joshua

+1

그 zip 라이브러리는 무엇입니까? 현재 메서드는 전체 파일을 MemoryStream으로 추출하므로 큰 파일에 대한 메모리 부족 예외가 발생할 수 있습니다. .NET 4.5에서 ['ZipArchiveEntry.Open'] (https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry.open)을 사용하여 [파일을 스트리밍] 할 수 있습니다 (http : //www.dotnetcurry.com/csharp/974/zip-archives-csharp-dotnet) – Slai

답변

2

파일이 유효한 XML 파일 인 경우는 전체 파일을 메모리로로드 피하기 위해 XmlReader을 사용할 수 있어야

string xmlText; 
using (var zip = ZipFile.Read(zipFileName)) 
{ 
    var ze = zip[zipPath]; 
    using (var ms = new MemoryStream()) 
    { 
     ze.Extract(ms); 
     ms.Position = 0; 
     using (var xml = XmlReader.Create(ms)) 
     { 
      if(xml.ReadToFollowing("someTag")) 
      { 
       xmlText = xml.ReadInnerXml(); 
      } 
      else 
      { 
       // <someTag> not found 
      } 
     } 
    } 
} 
파일이없는 경우 당신은 가능성이 잠재적 인 예외를 포착 할 수 있습니다

유효한 XML.

1

. (또한뿐만 아니라 사용에 위해 StreamReader를 넣어 있습니다.)

 using (var ms = new MemoryStream()) 
     { 
      ze.Extract(ms); 
      ms.Position = 0; 
      using (var sr = new StreamReader(ms)) 
      { 
       bool adding = false; 
       string startTag = "<someTag>"; 
       string endTag = "</someTag>"; 
       StringBuilder text = new StringBuilder(); 
       while (sr.Peek() >= 0) 
       { 
        string tmp = sr.ReadLine(); 
        if (!adding && tmp.Contains(startTag)) 
        { 
         adding = true; 
        } 
        if (adding) 
        { 
         text.Append(tmp); 
        } 
        if (tmp.Contains(endTag)) 
         break; 
       } 
       xmlText = text.ToString(); 
      } 
     } 

같은

뭔가 이것은 시작과 끝 태그 자체로 한 줄에 있다고 가정합니다. 그렇지 않다면, 시작과 끝 색인을 다시 가져 와서 원래의 텍스트 문자열을 정리할 수 있습니다.

관련 문제