2012-01-11 3 views
0

나는.NET에서 단일 TextWriter를 여러 출력으로 나누는 방법?

public void ExternalFactory.SetOut(TextWriter outputStream) 

나는 일반적으로 그냥 API는 자사의 모든 정보를 쓸 것으로

ExternalFactory.SetOut(Console.Out) 

같은이 메소드를 호출 다음 헤더와 방법을 가지고 내 C# 코드에서 API를 호출 콘솔. 그러나이 정보를 콘솔에 기록하는 것 외에도 텍스트 파일과 같은보다 영구적 인 장소에 저장하려고합니다.

첫 번째 추측은 스트림을 분할하고 Console과 StreamWriter 중 하나에 보내는 일종의 고객 TextWriter를 만들어야한다는 것입니다. 올바른 접근 방법은 무엇입니까?

답변

3

첫 번째 추측이 맞습니다. 당신은 그것을 일반화하고 텍스트 라이터의 목록을 건설 시간 매개 변수로 받아들이고 그것이받는 모든 입력을 모든 텍스트 작가에게 분배하는 '배포'텍스트 라이저를 작성할 수 있습니다.

+0

그래,이 방법으로, 내 DistributingTextWriter 콘솔 TextWriter 및 StreamWriter에 대한 참조를 보유한다고 가정합니다. 그런 다음 모든 Write 및 WriteLine 메서드를 덮어 써서이 호출을 모든 TextWriters에 '배포'해야합니까? – Nitax

+0

걱정됩니다. TextWriter 클래스의 인터페이스와의 호환성을 유지하려면 모든 메서드를 다시 구현해야합니다.그러나 System.IO.StreamWriter 구현에서 대부분의 코드를 복사 할 수 있습니다. "SSCLI"및/또는 "로터"에 대한 Google 검색. –

-2

데이터 사본을 스트림 (텍스트 파일)과 디스플레이 (콘솔)로 보낼 수 있습니다.

3

표준 I/O 기능보다는이 종류의 것에 대해서 log4net을 사용합니다. Log4net을 구성하여 ConsoleAppender와 FileAppender 또는 RollingFileAppender를 사용하여 동시에 콘솔과 로그 파일에 모두 기록합니다.

좋은 점은 기록 된 메시지 이외에 모든 종류의 유용한 정보 (시간, 스레드/프로세스 ID, 시스템 이름 등)를 저장하도록 로그 메시지 템플리트를 설정할 수 있다는 점입니다.

SQL Server, 이벤트 로그 또는 원격 싱크에 로그온 할 수도 있습니다.

쉽지!

using System; 
using System.IO; 
using System.Text; 
using log4net ; 

namespace ConsoleApplication22 
{ 
    public class Log4NetTextWriter : TextWriter, IDisposable 
    { 
     private static ILog log = log4net.LogManager.GetLogger(typeof(Log4NetTextWriter)) ; 

     #region properties 

     private StringBuilder buffer { get ; set ; } 

     public override Encoding Encoding 
     { 
      get 
      { 
       // since this TextWrite is writing to log4net, we have no idea what the final encoding might be. 
       // It all depends on the log4net configuration: tthe appender or appenders that wind up handling the logged message 
       // determine the final encoding. 
       // 
       // Might make more sense to return Encoding.UTF8 though, just to return something. 
       throw new NotImplementedException() ; 
      } 
     } 

     #endregion properties ; 

     public override void Flush() 
     { 
      if (this.buffer != null && this.buffer.Length > 0) 
      { 
       this.WriteLine() ; 
      } 
      return ; 
     } 

     public override void Close() 
     { 
      base.Close(); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      this.Flush() ; 
      base.Dispose(disposing); 
     } 

     #region public constructors 

     public Log4NetTextWriter() : this(null) 
     { 
      return ; 
     } 

     public Log4NetTextWriter(IFormatProvider formatProvider) : base(formatProvider) 
     { 
      this.buffer = new StringBuilder() ; 
     } 

     #endregion public constructors 

     #region public Write() overloads 
     public override void Write(bool value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(char value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(char[] buffer) 
     { 
      this.buffer.Append(buffer) ; 
      return ; 
     } 
     public override void Write(char[] buffer , int index , int count) 
     { 
      this.buffer.Append(buffer , index , count) ; 
      return ; 
     } 
     public override void Write(decimal value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(double value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(float value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(int value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(long value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(object value) 
     { 
      this.buffer.Append(value) ; 
      return ; 
     } 
     public override void Write(string format , object arg0) 
     { 
      this.buffer.AppendFormat(this.FormatProvider , format , arg0) ; 
      return ; 
     } 
     public override void Write(string format , object arg0 , object arg1) 
     { 
      this.buffer.AppendFormat(this.FormatProvider , format , arg0 , arg1) ; 
      return ; 
     } 
     public override void Write(string format , object arg0 , object arg1 , object arg2) 
     { 
      this.buffer.AppendFormat(this.FormatProvider , format , arg0 , arg1 , arg2); 
      return ; 
     } 
     public override void Write(string format , params object[] arg) 
     { 
      this.buffer.AppendFormat(this.FormatProvider , format , arg) ; 
      return ; 
     } 
     public override void Write(string value) 
     { 
      this.buffer.Append(value); 
      return ; 
     } 
     public override void Write(uint value) 
     { 
      this.buffer.Append(value); 
      return ; 
     } 
     public override void Write(ulong value) 
     { 
      this.buffer.Append(value); 
      return ; 
     } 
     public override void WriteLine() 
     { 
      string logMessage = this.buffer.ToString() ; 

      this.buffer.Length = 0 ; 
      log.Info(logMessage) ; 

      return ; 
     } 

     #endregion public Write() overloads 

     #region public WriteLine() overloads 

     public override void WriteLine(bool value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(char value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(char[] buffer) 
     { 
      this.Write(buffer) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(char[] buffer , int index , int count) 
     { 
      this.Write(buffer , index , count) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(decimal value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(double value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(float value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(int value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(long value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(object value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(string format , object arg0) 
     { 
      this.Write(format , arg0) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(string format , object arg0 , object arg1) 
     { 
      this.Write(format , arg0 , arg1) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(string format , object arg0 , object arg1 , object arg2) 
     { 
      this.Write(format , arg0 , arg1 , arg2) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(string format , params object[] arg) 
     { 
      this.Write(format , arg) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(string value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(uint value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 
     public override void WriteLine(ulong value) 
     { 
      this.Write(value) ; 
      this.WriteLine() ; 
      return ; 
     } 

     #endregion public WriteLine() overloads 

    } 
} 

다음은 샘플 log4net 설정 파일입니다 :

여기에 log4net을 통해 경로의 모든 것을 샘플 TextWriter를 구현합니다. 이 로그 파일은 콘솔과 로그 파일에 기록되며 크기에 따라 자동으로 롤오버됩니다 (날짜/시간 또는 실행 당 롤 수 있음). 프로그램이 실행되는

// Configure log4net using the .log4net file 
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net",Watch=true)] 
// This will cause log4net to look for a configuration file 
// called TestApp.exe.log4net in the application base 
// directory (i.e. the directory containing TestApp.exe) 
// The config file will be watched for changes. 

동안, 당신은 로깅 설정하거나 해제 또는 변경할 수 있습니다 log4net를 구성하려면

<log4net> 

    <!-- Log to the console --> 
    <appender name="Console" type="log4net.Appender.ConsoleAppender"> 
    <layout type="log4net.Layout.PatternLayout"> 
     <!-- Pattern to output the caller's file name and line number --> 
     <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" /> 
    </layout> 
    </appender> 

    <!-- Log to a log file. This particular setup should log to a static file name 'log.txt' --> 
    <!-- When it hits 100KB in size, it rolls, keeping up to 10 archived files. The archived --> 
    <!-- files are named 'log.text.1', 'log.txt.2', ... , 'log.txt.10' --> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
    <file value="log.txt" /> 
    <appendToFile value="true" /> 
    <rollingStyle value="Size" /> 
    <maxSizeRollBackups value="10" /> 
    <maximumFileSize value="100KB" /> 
    <staticLogFileName value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 
    </layout> 
    </appender> 

    <root> 
    <level value="DEBUG" /> 
    <appender-ref ref="Console" /> 
    <appender-ref ref="RollingFile" /> 
    </root> 

</log4net> 

는 가장 쉬운 방법은, 따라서,의 AssemblyInfo.cs에 XmlConfigurator 속성을 넣어이다 구성 파일을 편집하고 저장하면됩니다. log4net은 설정 파일 변경을 감시하고 즉시 변경됩니다.

+0

Log4net 전문가가 아니지만이 외부 라이브러리에 전달할 수있는 단일 TextWriter 개체를 만들 수 없으면 내 문제가 해결되지 않습니다. – Nitax

+0

@Nitax : 내 대답에 대한 추가 내용보기 위에 –

2

컴파일 및 첫 번째 사용 이외의 테스트는 수행되지 않지만 누군가 입력하는 시간을 절약 할 수 있습니다. 짜증나는 것은 이미 존재하지 않습니다.

/// <summary> 
/// Spreads data out to multiple text writers. 
/// </summary> 
class TextWriterMulti : System.IO.TextWriter 
{ 
    private System.Collections.Generic.List<System.IO.TextWriter> writers = new System.Collections.Generic.List<System.IO.TextWriter>(); 
    private System.IFormatProvider formatProvider = null; 
    private System.Text.Encoding encoding = null; 

    #region TextWriter Properties 
    public override System.IFormatProvider FormatProvider 
    { 
     get 
     { 
      System.IFormatProvider formatProvider = this.formatProvider; 
      if (formatProvider == null) 
      { 
       formatProvider = base.FormatProvider; 
      } 
      return formatProvider; 
     } 
    } 

    public override string NewLine 
    { 
     get { return base.NewLine; } 

     set 
     { 
      foreach (System.IO.TextWriter writer in this.writers) 
      { 
       writer.NewLine = value; 
      } 

      base.NewLine = value; 
     } 
    } 


    public override System.Text.Encoding Encoding 
    { 
     get 
     { 
      System.Text.Encoding encoding = this.encoding; 

      if (encoding == null) 
      { 
       encoding = System.Text.Encoding.Default; 
      } 

      return encoding; 
     } 
    } 

    #region TextWriter Property Setters 

    TextWriterMulti SetFormatProvider(System.IFormatProvider value) 
    { 
     this.formatProvider = value; 
     return this; 
    } 

    TextWriterMulti SetEncoding(System.Text.Encoding value) 
    { 
     this.encoding = value; 
     return this; 
    } 
    #endregion // TextWriter Property Setters 
    #endregion // TextWriter Properties 


    #region Construction/Destruction 
    public TextWriterMulti(System.Collections.Generic.IEnumerable<System.IO.TextWriter> writers) 
    { 
     this.Clear(); 
     this.AddWriters(writers); 
    } 
    #endregion // Construction/Destruction 

    #region Public interface 
    public TextWriterMulti Clear() 
    { 
     this.writers.Clear(); 
     return this; 
    } 

    public TextWriterMulti AddWriter(System.IO.TextWriter writer) 
    { 
     this.writers.Add(writer); 
     return this; 
    } 

    public TextWriterMulti AddWriters(System.Collections.Generic.IEnumerable<System.IO.TextWriter> writers) 
    { 
     this.writers.AddRange(writers); 
     return this; 
    } 
    #endregion // Public interface 

    #region TextWriter methods 

    public override void Close() 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Close(); 
     } 
     base.Close(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      if (disposing) 
      { 
       writer.Dispose(); 
      } 
     } 
     base.Dispose(disposing); 
    } 

    public override void Flush() 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Flush(); 
     } 

     base.Flush(); 
    } 

    //foreach (System.IO.TextWriter writer in this.writers) 
    //{ 
    // writer; 
    //} 
    public override void Write(bool value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(char value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(char[] buffer) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(buffer); 
     } 
    } 

    public override void Write(decimal value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(double value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(float value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(int value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(long value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(object value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(string value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(uint value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(ulong value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(value); 
     } 
    } 

    public override void Write(string format, object arg0) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(format, arg0); 
     } 

    } 

    public override void Write(string format, params object[] arg) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(format, arg); 
     } 
    } 

    public override void Write(char[] buffer, int index, int count) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(buffer, index, count); 
     } 
    } 

    public override void Write(string format, object arg0, object arg1) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(format, arg0, arg1); 
     } 
    } 

    public override void Write(string format, object arg0, object arg1, object arg2) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.Write(format, arg0, arg1, arg2); 
     } 
    } 

    public override void WriteLine() 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(); 
     } 
    } 

    public override void WriteLine(bool value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(char value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(char[] buffer) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(buffer); 
     } 
    } 

    public override void WriteLine(decimal value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(double value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(float value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(int value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(long value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(object value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(string value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(uint value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(ulong value) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(value); 
     } 
    } 

    public override void WriteLine(string format, object arg0) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(format, arg0); 
     } 
    } 

    public override void WriteLine(string format, params object[] arg) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(format, arg); 
     } 
    } 

    public override void WriteLine(char[] buffer, int index, int count) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(buffer, index, count); 
     } 
    } 

    public override void WriteLine(string format, object arg0, object arg1) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(format, arg0, arg1); 
     } 
    } 

    public override void WriteLine(string format, object arg0, object arg1, object arg2) 
    { 
     foreach (System.IO.TextWriter writer in this.writers) 
     { 
      writer.WriteLine(format, arg0, arg1, arg2); 
     } 
    } 
    #endregion // TextWriter methods 
} 
관련 문제