2010-05-27 2 views
5

나는 3 개의 TextReader, 즉 StreamReaders와 StringReaders를 가지고있다. 개념적으로, 이들의 연결은 하나의 텍스트 문서입니다.여러 TextReaders를 함께 문자열링하는 방법은 무엇입니까?

단일 TextReader를 사용하는 방법 (내 제어가 아님)을 호출하려고합니다. 여러 TextReaders에서 TextReader를 연결하는 내장 또는 쉬운 방법이 있습니까?

(은 내 자신의 TextReader 하위 클래스를 작성할 수 있지만 상당한 양의 작업으로 보입니다.이 경우 임시 파일에 모두 쓰고 단일 StreamReader로 열면됩니다.)

내가 쉽게 찾을 수없는 쉬운 해결책이 있습니까?

답변

5

방금 ​​이걸 던져 버렸으므로 매우 견고하지 않습니다 (오류 처리 등 없음).하지만 기본 테스트 사례가 작동합니다.

그것은 둘째을 TextReader 년대에 대한 확장 메서드를 작성하여 작동하고,이 떨어지기까지 내부적으로 처음에 Read()를 호출하는 새로운 TextReader를 클래스를 반환 한 다음 두 번째에 Read()를 호출 시작합니다. 이것을 무한대로 연결할 수 있습니다.

Read(), Peek(), Close()Dispose()을 구현하는 경우에만 필요 TextReader의 완전한 구현을 제공합니다. 다른 모든 방법은 특정 구현 Read()에 의존합니다. 그래서 자신의 TextReader을 만드는 것은 그렇게 나쁘지 않습니다. 아래에서 볼 수 있습니다.

이렇게하면 기존 TextReaders를 단순히 래핑하고 연결을 수행하기 위해 실제로 호출하지 않기 때문에 성능 문제가 완화됩니다.

class Program 
{ 
    static void Main(string[] args) 
    { 
     StringReader first = new StringReader("hello "); 
     StringReader second = new StringReader("world"); 
     StringReader third = new StringReader("!"); 

     using (var allOfThem = first.Concat(second).Concat(third)) 
     { 
      //writes "hello world!" 
      Console.WriteLine(allOfThem.ReadToEnd()); 
     } 
     Console.Read(); 
    } 
} 

public static class Extensions 
{ 
    public static TextReader Concat(this TextReader first, TextReader second) 
    { 
     return new ChainedTextReader(first, second); 
    } 

    private class ChainedTextReader : TextReader 
    { 
     private TextReader first; 
     private TextReader second; 
     private bool readFirst = true; 

     public ChainedTextReader(TextReader first, TextReader second) 
     { 
      this.first = first; 
      this.second = second; 
     } 

     public override int Peek() 
     { 
      if (readFirst) 
      { 
       return first.Peek(); 
      } 
      else 
      { 
       return second.Peek(); 
      } 
     } 

     public override int Read() 
     { 
      if (readFirst) 
      { 
       int value = first.Read(); 
       if (value == -1) 
       { 
        readFirst = false; 
       } 
       else 
       { 
        return value; 
       } 
      } 
      return second.Read(); 
     } 

     public override void Close() 
     { 
      first.Close(); 
      second.Close(); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      base.Dispose(disposing); 
      if (disposing) 
      { 
       first.Dispose(); 
       second.Dispose(); 
      } 
     } 
    } 
} 
+1

아, 그건 영리합니다. 오직 2 개만 처리하고 확장 방법을 사용하여 연결합니다. – Ken

관련 문제