将控制台输出镜像到文件
在C#控制台应用程序中,是否有将控制台输出镜像到文本文件的巧妙方法?
目前我只是在日志方法中传递相同的stringConsole.WriteLine
和InstanceOfStreamWriter.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); } } }