2012-01-11 43 views
0

我把從我的C#代碼,與下面的頭一個方法的API如何在.NET中將單個TextWriter分成多個輸出?

public void ExternalFactory.SetOut(TextWriter outputStream) 

我通常調用這個方法就像

ExternalFactory.SetOut(Console.Out) 

只是使API編寫所有的信息到安慰。但是,除了寫入控制檯以外,我還希望將這些信息存儲在更加固定的位置,例如文本文件。

我的第一個猜測是我需要創建一些客戶TextWriter來分割流,並將一個發送到控制檯,一個發送到StreamWriter。這裏的正確方法是什麼?

回答

3

你的第一個猜測是正確的。你可以概括它,並寫一個'發佈'的textwriter,它接受一個textwriters列表作爲構造時間參數,並將它收到的所有輸入分發給每一個textwriters。

+0

好吧,用這種方法,我假設我的DistributingTextWriter會持有對控制檯TextWriter和StreamWriter的引用。那麼我是否必須重寫每個Write和WriteLine方法以將這些調用「分配」給所有TextWriters? – Nitax 2012-01-11 18:52:34

+0

恐怕是這樣的:如果你想保持與TextWriter類的接口的兼容性,你將不得不重新實現所有這些方法。但是,您可以從System.IO.StreamWriter的實現中複製大部分代碼。谷歌的「SSCLI」和/或「轉子」來找到它。 – 2012-01-11 19:03:36

-2

您只需將數據副本發送到流(文本文件)和顯示器(控制檯)即可。

3

而不是標準的I/O設施,我使用log4net這種事情。我將log4net配置爲使用ConsoleAppender和FileAppender或RollingFileAppender同時登錄到控制檯和日誌文件。

好的是您可以設置日誌消息模板來捕獲各種有用的信息(時間,線程/進程ID,機器名稱等),除了記錄的消息。

您還可以登錄到SQL Server,事件日誌或遠程接收器。

簡單!

這裏是一個樣本的TextWriter實現的路由一切通過log4net的:

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> 

    <!-- 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> 

要配置log4net的,最簡單的方法是把一個XmlConfigurator屬性在AssemblyInfo.cs中,這樣的:

// 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監視配置文件的變化並在運行中自行重新配置。

+0

我不是log4net的專家,但除非它允許我創建一個可傳遞給此外部庫的單個TextWriter對象,否則這對我的問題不起作用... – Nitax 2012-01-11 20:24:31

+0

@Nitax:請參閱我的答案以上 – 2012-01-11 22:03:08

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 
} 
相關問題