当前位置: 首页 > 工具软件 > API Console > 使用案例 >

将C#的Console.Write同步到控制台和log文件输出

红砚文
2023-12-01

将C#的Console.Write同步到控制台和log文件输出

日常编写小工具时,使用Console.Write会把日志输出到控制台中,这便于在运行过程查看日志,但如果日志过多,或者希望能对日志进行查找,复制操作时,在控制台中就不方便操作了,这时就希望能把日志输出到log文件中,通过Console.SetOut可以将输出重定向到文件,不过这样就不方便在运行时查看日志进度。有没有办法可以把日志同步输出到控制台和log文件中呢?
参考StackOverflow的一个回答,其实原理很简单,就是我们自己实现一个TextWriter,它接收一个文件和原Console的输出流,然后将输出重定向到这个TextWriter,就可以了。
代码如下:

public class ConsoleCopy : IDisposable
{
    private FileStream m_FileStream;
    private StreamWriter m_FileWriter;

    private readonly TextWriter m_DoubleWriter;
    private readonly TextWriter m_OldOut;

    private class DoubleWriter : TextWriter
    {
        private TextWriter m_One;
        private TextWriter m_Two;

        public DoubleWriter(TextWriter one, TextWriter two)
        {
            m_One = one;
            m_Two = two;
        }

        public override Encoding Encoding
        {
            get { return m_One.Encoding; }
        }

        public override void Flush()
        {
            m_One.Flush();
            m_Two.Flush();
        }

        public override void Write(char value)
        {
            m_One.Write(value);
            m_Two.Write(value);
        }
    }

    public ConsoleCopy(string path)
    {
        m_OldOut = Console.Out;

        try {
            m_FileStream = File.Create(path);

            m_FileWriter = new StreamWriter(m_FileStream)
            {
                AutoFlush = true
            };

            m_DoubleWriter = new DoubleWriter(m_FileWriter, m_OldOut);
        }
        catch (Exception e) {
            Console.WriteLine("Cannot open file for writing");
            Console.WriteLine(e.Message);
            return;
        }
        Console.SetOut(m_DoubleWriter);
    }

    public void Dispose()
    {
        Console.SetOut(m_OldOut);

        if (m_FileWriter != null) {
            m_FileWriter.Flush();
            m_FileWriter.Close();
            m_FileWriter = null;
        }
        if (m_FileStream != null) {
            m_FileStream.Close();
            m_FileStream = null;
        }
    }
}

使用方法如下:

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

这个方法最大的好处就是不用修改原有的Console.Write,只要在程序入口处将主逻辑用using包住,内部所有的输出都能同步输出到控制台和log文件了。

 类似资料: