将控制台输出镜像到文件

在C#控制台应用程序中,是否有将控制台输出镜像到文本文件的巧妙方法?

目前我只是在日志方法中传递相同的stringConsole.WriteLineInstanceOfStreamWriter.WriteLine

这可能是一些更多的工作,但我会反过来。

为控制台实例化一个TraceListener ,为日志文件实例化一个TraceListener ; 之后在代码中使用Trace.Write语句而不是Console.Write 。 之后,删除日志,控制台输出或附加其他日志logging机制变得更加容易。

 static void Main(string[] args) { Trace.Listeners.Clear(); TextWriterTraceListener twtl = new TextWriterTraceListener(Path.Combine(Path.GetTempPath(), AppDomain.CurrentDomain.FriendlyName)); twtl.Name = "TextLogger"; twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime; ConsoleTraceListener ctl = new ConsoleTraceListener(false); ctl.TraceOutputOptions = TraceOptions.DateTime; Trace.Listeners.Add(twtl); Trace.Listeners.Add(ctl); Trace.AutoFlush = true; Trace.WriteLine("The first line to be in the logfile and on the console."); } 

据我所知,您可以在应用程序configuration中定义侦听器,从而可以在不触摸构build的情况下激活或停用日志logging。

这是一个简单的类,它是TextWriter的子类,允许将inputredirect到文件和控制台。

像这样使用它

  using (var cc = new ConsoleCopy("mylogfile.txt")) { Console.WriteLine("testing 1-2-3"); Console.WriteLine("testing 4-5-6"); Console.ReadKey(); } 

这是class级:

 class ConsoleCopy : IDisposable { FileStream fileStream; StreamWriter fileWriter; TextWriter doubleWriter; TextWriter oldOut; class DoubleWriter : TextWriter { TextWriter one; TextWriter two; public DoubleWriter(TextWriter one, TextWriter two) { this.one = one; this.two = two; } public override Encoding Encoding { get { return one.Encoding; } } public override void Flush() { one.Flush(); two.Flush(); } public override void Write(char value) { one.Write(value); two.Write(value); } } public ConsoleCopy(string path) { oldOut = Console.Out; try { fileStream = File.Create(path); fileWriter = new StreamWriter(fileStream); fileWriter.AutoFlush = true; doubleWriter = new DoubleWriter(fileWriter, oldOut); } catch (Exception e) { Console.WriteLine("Cannot open file for writing"); Console.WriteLine(e.Message); return; } Console.SetOut(doubleWriter); } public void Dispose() { Console.SetOut(oldOut); if (fileWriter != null) { fileWriter.Flush(); fileWriter.Close(); fileWriter = null; } if (fileStream != null) { fileStream.Close(); fileStream = null; } } } 

检查log4net 。 通过log4net,您可以设置控制台和文件appender,它们可以使用单个日志语句将日志消息输出到两个地方。

您可以inheritanceTextWriter类,然后使用Console.SetOut方法将其实例分配给Console.Out – 特别是将相同的string传递给log方法中的两个方法。

另一种方法可能会声明自己的Console类,并使用using语句来区分类:

 using Console = My.Very.Own.Little.Console; 

要访问标准控制台,您需要:

 global::Console.Whatever 

难道你不能只是使用>命令redirect到一个文件的输出?

 c:\>Console.exe > c:/temp/output.txt 

如果你需要镜像,你可以尝试find一个win32版本的tee ,将输出分割成一个文件。

Log4net可以为你做到这一点。 你只会写这样的东西:

 logger.info("Message"); 

configuration将确定打印输出是否将转到控制台,文件或两者。

正如我从这里学到的,真的需要在这里分享我的解决scheme。

首先,我们需要创buildStreamWriter固有的新类,比如CombinedWriter;

然后用Console.Out初始化CombinedWriter的一个新的瞬间;

最后,我们可以通过Console.SetOut将控制台输出redirect到新类的时刻;

下面的代码是新的类为我工作。

 public class CombinedWriter : StreamWriter { TextWriter console; public CombinedWriter(string path, bool append, Encoding encoding, int bufferSize, TextWriter console) :base(path, append, encoding, bufferSize) { this.console = console; base.AutoFlush = true; // thanks for @konoplinovich reminding } public override void Write(string value) { console.Write(value); base.Write(value); } } 

正如Arul所build议的那样,使用Console.SetOut可以将输出redirect到一个文本文件:

 Console.SetOut(new StreamWriter("Output.txt")); 

我认为你已经使用的是最好的方法。 实质上镜像您的输出的简单方法。

首先在开始时声明一个全局TextWriter:

 private TextWriter txtMirror = new StreamWriter("mirror.txt"); 

然后制作一个写作方法:

 // Write empty line private void Log() { Console.WriteLine(); txtMirror.WriteLine(); } // Write text private void Log(string strText) { Console.WriteLine(strText); txtMirror.WriteLine(strText); } 

现在,而不是使用Console.WriteLine("..."); ,使用Log("..."); 。 就那么简单。 它甚至更短!


如果你移动了游标的位置( Console.SetCursorPosition(x, y); ),那么可能会有一些麻烦,但是其他方式也可以,我自己也是这样使用的!

编辑

当然你可以为Console.Write(); 如果你不使用WriteLines,也是一样

决定使用从StreamWriterinheritance的类,由用户Keep Thinking提供的build议起作用。 但我不得不添加到构造函数base.AutoFlush = true:

 { this.console = console; base.AutoFlush = true; } 

并显式调用析构函数:

 public new void Dispose () { base.Dispose (); } 

否则,文件比他logging的所有数据更早closures。

我正在使用它:

 CombinedWriter cw = new CombinedWriter ( "out.txt", true, Encoding.Unicode, 512, Console.Out ); Console.SetOut (cw); 

感谢您继续为优秀的解决scheme思考! 我添加了一些覆盖,以避免logging某些控制台写事件(为我的目的)仅用于控制台显示。

 using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; namespace RedirectOutput { public class CombinedWriter : StreamWriter { TextWriter console; public CombinedWriter(string path, bool append, TextWriter consoleout) : base(path, append) { this.console = consoleout; base.AutoFlush = true; } public override void Write(string value) { console.Write(value); //base.Write(value);//do not log writes without line ends as these are only for console display } public override void WriteLine() { console.WriteLine(); //base.WriteLine();//do not log empty writes as these are only for advancing console display } public override void WriteLine(string value) { console.WriteLine(value); if (value != "") { base.WriteLine(value); } } public new void Dispose() { base.Dispose(); } } class Program { static void Main(string[] args) { CombinedWriter cw = new CombinedWriter("combined.log", false, Console.Out); Console.SetOut(cw); Console.WriteLine("Line 1"); Console.WriteLine(); Console.WriteLine("Line 2"); Console.WriteLine(""); for (int i = 0; i < 10; i++) { Console.Write("Waiting " + i.ToString()); Console.CursorLeft = 0; } Console.WriteLine(); for (int i = 0; i < 10; i++) { Console.Write("Waiting " + i.ToString()); } Console.WriteLine(); Console.WriteLine("Line 3"); cw.Dispose(); } } } 

实际上,您可以通过实现自己的inheritance自TextWriter的类并重写WriteLine方法来创buildConsole.Out的透明镜像。

在WriteLine中,您可以将其写入Trace,然后将其configuration为写入文件。

我发现这个答案非常有用: https : //stackoverflow.com/a/10918320/379132

它真的为我工作!

如果您从您不控制的代码(例如第三方库)复制控制台输出,则应覆盖TextWriter的所有成员。 代码使用这个线程的想法。

用法:

 using (StreamWriter writer = new StreamWriter(filePath)) { using (new ConsoleMirroring(writer)) { // code using console output } } 

ConsoleMirroring类

 public class ConsoleMirroring : TextWriter { private TextWriter _consoleOutput; private TextWriter _consoleError; private StreamWriter _streamWriter; public ConsoleMirroring(StreamWriter streamWriter) { this._streamWriter = streamWriter; _consoleOutput = Console.Out; _consoleError = Console.Error; Console.SetOut(this); Console.SetError(this); } public override Encoding Encoding { get { return _consoleOutput.Encoding; } } public override IFormatProvider FormatProvider { get { return _consoleOutput.FormatProvider; } } public override string NewLine { get { return _consoleOutput.NewLine; } set { _consoleOutput.NewLine = value; } } public override void Close() { _consoleOutput.Close(); _streamWriter.Close(); } public override void Flush() { _consoleOutput.Flush(); _streamWriter.Flush(); } public override void Write(double value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(string value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(object value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(decimal value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(float value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(bool value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(int value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(uint value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(ulong value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(long value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(char[] buffer) { _consoleOutput.Write(buffer); _streamWriter.Write(buffer); } public override void Write(char value) { _consoleOutput.Write(value); _streamWriter.Write(value); } public override void Write(string format, params object[] arg) { _consoleOutput.Write(format, arg); _streamWriter.Write(format, arg); } public override void Write(string format, object arg0) { _consoleOutput.Write(format, arg0); _streamWriter.Write(format, arg0); } public override void Write(string format, object arg0, object arg1) { _consoleOutput.Write(format, arg0, arg1); _streamWriter.Write(format, arg0, arg1); } public override void Write(char[] buffer, int index, int count) { _consoleOutput.Write(buffer, index, count); _streamWriter.Write(buffer, index, count); } public override void Write(string format, object arg0, object arg1, object arg2) { _consoleOutput.Write(format, arg0, arg1, arg2); _streamWriter.Write(format, arg0, arg1, arg2); } public override void WriteLine() { _consoleOutput.WriteLine(); _streamWriter.WriteLine(); } public override void WriteLine(double value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(decimal value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(string value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(object value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(float value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(bool value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(uint value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(long value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(ulong value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(int value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(char[] buffer) { _consoleOutput.WriteLine(buffer); _streamWriter.WriteLine(buffer); } public override void WriteLine(char value) { _consoleOutput.WriteLine(value); _streamWriter.WriteLine(value); } public override void WriteLine(string format, params object[] arg) { _consoleOutput.WriteLine(format, arg); _streamWriter.WriteLine(format, arg); } public override void WriteLine(string format, object arg0) { _consoleOutput.WriteLine(format, arg0); _streamWriter.WriteLine(format, arg0); } public override void WriteLine(string format, object arg0, object arg1) { _consoleOutput.WriteLine(format, arg0, arg1); _streamWriter.WriteLine(format, arg0, arg1); } public override void WriteLine(char[] buffer, int index, int count) { _consoleOutput.WriteLine(buffer, index, count); _streamWriter.WriteLine(buffer, index, count); } public override void WriteLine(string format, object arg0, object arg1, object arg2) { _consoleOutput.WriteLine(format, arg0, arg1, arg2); _streamWriter.WriteLine(format, arg0, arg1, arg2); } protected override void Dispose(bool disposing) { if (disposing) { Console.SetOut(_consoleOutput); Console.SetError(_consoleError); } } }