Multiple console output in C#

Write console output to file and screen at the same time

  • Share

Console applications are the simplest one and very convenient when you need to quickly test some functionality. Some time the functionality that you test with console application may take time and since it is test usually it happens that it crashes. You can always use some logger for example Log4Net but you would have to include it in project and setup.

System.Console however supports different output, but you can only switch output, so either you use screen of file or some other place where you write the output. This means if you for example switch to file you will not get the messages on the screen :(

Method SetOut accepts TextWriter instance as a parameter which is abstract class meaning you can write your own logic for writing the output.

You can easily override WriteLine method, but when you do that every time you invoke Console.WriteLine you will end up in the override method in your class and end up with StackOverflowException thrown. To avoid this you need to switch between old out put and new output when writing as in the following class.

using System;
using System.IO;
using System.Text;

namespace MultiConsoleOutput
{
    public class ConsoleFileOutput : TextWriter
    {
        #region Fields
        private Encoding encoding = Encoding.UTF8;
        private StreamWriter writer;
        private TextWriter console;
        #endregion

        #region Properties
        public override Encoding Encoding
        {
            get
            {
                return encoding;
            }
        }
        #endregion

        #region Constructors
        public ConsoleFileOutput(string filePath,TextWriter console, Encoding encoding = null)
        {
            if (encoding != null)
            {
                this.encoding = encoding;
            }
            this.console = console;
            this.writer = new StreamWriter(filePath,false, this.encoding);
            this.writer.AutoFlush = true;
        }
        #endregion

        #region Overrides
        public override void Write(string value)
        {
            Console.SetOut(console);
            Console.Write(value);
            Console.SetOut(this);
            this.writer.Write(value);
        }

        public override void WriteLine(string value)
        {
            Console.SetOut(console);
            Console.WriteLine(value);
            this.writer.WriteLine(value);
            Console.SetOut(this);
        }

        public override void Flush()
        {
            this.writer.Flush();
        }

        public override void Close()
        {
            this.writer.Close();
        }
        #endregion

        #region IDisposable
        public void Dispose()
        {
            this.writer.Flush();
            this.writer.Close();
            this.writer.Dispose();
            base.Dispose();
        }
        #endregion
    }
}

    

The constructor of ConsoleFileOutput requires file path and previous console out (encoding is an optional parameter and UTF8 will be used by default). This allows switching between new output and the old one when writing the message.

In short words you just need to set the console output to an instance of ConsoleFileOutput class and you will get your output in both screen and text file. Check the following code snippet for creating the multiple output from the console:

using System;

namespace MultiConsoleOutput
{
    class Program
    {
        static void Main(string[] args)
        {
            var dualOutput = new ConsoleFileOutput(@"d:\temp\consoleout.txt", Console.Out);
            Console.SetOut(dualOutput);
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
            }
            Console.ReadLine();
        }
    }
}

    

The same way writing the output to file is done, it can be done with any other type of output like database for example.

References

  • Share

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.

Comments for this article

comments powered by Disqus