2012-01-11 3 views
0

я называю API из моего C# код, который имеет метод со следующим заголовкомКак разделить один TextWriter на несколько выходов в .NET?

public void ExternalFactory.SetOut(TextWriter outputStream) 

Я обычно называю этот метод, как

ExternalFactory.SetOut(Console.Out) 

чтобы просто написать API писать всю свою информацию в Консоль. Тем не менее, я также хотел бы сохранить эту информацию в более постоянном месте, таком как текстовый файл, в дополнение к тому, чтобы быть записанным на консоль.

Моя первая предпосылка заключается в том, что мне нужно создать своего рода клиент TextWriter, который разбивает поток и отправляет его на консоль, а другой - в StreamWriter. Каков правильный подход?

ответ

3

Ваше первое предположение верно. Вы можете обобщить его и написать «распределяющий» текстовый редактор, который принимает список текстовых элементов как параметр времени построения и распределяет все входные данные, которые он получает, каждому из текстовых редакторов.

+0

Хорошо, с помощью этого метода я предполагаю, что мой DistributingTextWriter будет содержать ссылку на Консоль TextWriter и StreamWriter. Должен ли я затем перезаписывать каждый метод Write и WriteLine для «распределения» этих вызовов ко всем TextWriters? – Nitax

+0

Я боюсь так: вам придется переопределить все эти методы, если вы хотите поддерживать совместимость с интерфейсом класса TextWriter.Однако вы можете скопировать большую часть кода из реализации System.IO.StreamWriter. Google для «SSCLI» и/или «Rotor», чтобы найти его. –

-2

Вы можете просто отправить копию данных как в поток (текстовый файл), так и на дисплей (консоль).

3

Вместо стандартных устройств ввода-вывода я использую log4net для такого рода вещей. Я настраиваю log4net для одновременного входа в консоль и файл журнала с помощью ConsoleAppender и FileAppender или RollingFileAppender.

Приятно то, что вы можете установить шаблон сообщения журнала, чтобы уловить всевозможную полезную информацию (время суток, идентификатор потока/процесса, имя машины и т. Д.) В дополнение к только зарегистрированному сообщению.

Вы также можете войти в 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

+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 
} 
Смежные вопросы