2012-01-11 6 views
0

私は通常、ちょうどAPIはにその情報のすべてを書く持って.NETで単一のTextWriterを複数の出力に分割する方法

ExternalFactory.SetOut(Console.Out) 

のように、このメソッドを呼び出して、次のヘッダ

public void ExternalFactory.SetOut(TextWriter outputStream) 

と方法を持っている私のC#コードからAPIを呼び出しますコンソール。しかし、私はまた、コンソールに書き込まれるだけでなく、テキストファイルなどのより永続的な場所にこの情報を保存したいと考えています。

まず、ストリームを分割して1つをコンソールに、もう1つをStreamWriterに送信する、ある種の顧客TextWriterを作成する必要があると思います。ここで正しいアプローチは何ですか?

答えて

3

あなたの最初の推測は正しいです。それを一般化して、テキストライターのリストを受け取り、作成時のパラメーターとして受け取り、受け取ったすべての入力をテキストライターのすべての1人に配布する '配布'テキストライターを書くことができます。

+0

このメソッドでは、私はDistributingTextWriterがConsole TextWriterとStreamWriterへの参照を保持していると仮定しています。これらの呼び出しをすべてのTextWriterに '配布'するために、それぞれのWriteメソッドとWriteLineメソッドを上書きする必要がありますか? – Nitax

+0

私は心配です:TextWriterクラスのインターフェイスとの互換性を維持するには、これらのメソッドをすべて再実装する必要があります。ただし、ほとんどのコードをSystem.IO.StreamWriterの実装からコピーできます。 "SSCLI"と "Rotor"のGoogle検索で検索できます。 –

-2

ストリームの(テキストファイル)と表示(コンソール)の両方にデータのコピーを送信することができます。

3

標準I/O機能ではなく、この種のものにはlog4netを使用します。私は、ConsoleAppenderとFileAppenderまたはRollingFileAppenderを使用して、log4netをコンソールとログファイルの両方に同時にログオンするように設定します。

素晴らしいことは、ログメッセージテンプレートだけでなく、ログメッセージだけでなく、あらゆる種類の有用な情報(時刻、スレッド/プロセスID、マシン名など)をトラップできることです。

SQL Server、イベントログ、またはリモートシンクにもログオンできます。

Easy!

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> 

    <!-- 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のを設定するには、最も簡単な方法は、このように、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 
} 
関連する問題