2

I searched lots in internet to store the console application output screen in .txt file. I got the solution but i did not got the desired results. The problem is the text which was not display in console screen was stored in the notepad file. But the text displayed in the console screen was not stored in the notepad file.

For example,

using System;
using System.IO;


static void Main(string[] args)
        {

            Console.WriteLine("Text which is displayed in the the console output screen ");
            FileStream filestream = new FileStream("notepad.txt", FileMode.Create);
            var streamwriter = new StreamWriter(filestream);
            streamwriter.AutoFlush = true;
            Console.SetOut(streamwriter);
            Console.SetError(streamwriter);
            Console.WriteLine("Text which is not displayed in the console output screen but it store in the the .txt file");
            Console.ReadKey();
        }

In above example
The line Console.WriteLine("Text which is displayed in the the console output screen "); is just displayed in the console screen but it was not store in the notepad file

But the line Console.WriteLine("Text which is not displayed in the console output screen but it store in the the .txt file"); is not displayed in the console application screen instead of it was stored in the notepad file.

I need to store everything whatever displayed in the console screen even user given details too.

How do I do it?

As I am a beginner, I expecting the answer would be simple.

Thanks in advance!

  • 1
    http://stackoverflow.com/questions/4470700/how-to-save-console-writeline-output-to-text-file – deChristo Nov 25 '16 at 11:07
  • http://stackoverflow.com/questions/420429/mirroring-console-output-to-a-file – tolanj Nov 25 '16 at 11:16
  • 1
    Just a sidenote for your example - `FileStream` and `StreamWriter` implement `IDisposable` interface and so they should be disposed of. For example `using(FileStream filestream = new FileStream("notepad.txt", FileMode.Create)){ /* use filestream */ ... }` You can learn more about Dispose pattern at https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx. – davke Nov 25 '16 at 11:58

1 Answers1

6

You can only assign one output stream to the console. So you will need a stream that does both, writing to the screen and to a file.

You can always get standard output stream of the console like this:

Stream consoleOutput = Console.GetStandardOutput();

If you want to use multiple outputs, you have to create a new stream class that will distribute the data to multiple streams. For that you will have to overwrite the Stream class (not a full implementation, you will have to implement all other abstract members of Stream, too):

public class MultiStream : Stream {
    private readonly Stream[] m_children;

    public MultiStream(params Stream[] children) {
        m_children = children;
    }

    public override Write(byte[] buffer, int offset, int count) {
        foreach(Stream child in m_children) {
            child.Write(buffer, offset, count);
        }
    }

    //...
}

Now you can use your MultiStream to route your output to multiple streams:

        FileStream filestream = new FileStream("notepad.txt", FileMode.Create);
        MultiStream outStream = new MultiStream(filestream, Console.GetStandardOutput());
        var streamwriter = new StreamWriter(outStream);

If you are OK to replace Console.WriteLine, you could use a simpler way (assuming your streamwriter variable is accessible):

public void WriteLineToScreenAndFile(string text) {
    Console.WriteLine(text);
    streamwriter.WriteLine(text);
}

You can replace all calls to Console.WriteLine with a call to that method.

Sefe
  • 13,731
  • 5
  • 42
  • 55
  • 1
    Nice solution, I'm not sure it'll be accessable to a beginner though. – BanksySan Nov 25 '16 at 11:31
  • 1
    Sorry for that. I can't think of another solution though. – Sefe Nov 25 '16 at 11:33
  • Ii can only think of writing a wrapper around `Console.WriteLine` that writes to both file and screen. You solution is much neater. Wrapper might be a shallower learning curve though. – BanksySan Nov 25 '16 at 11:42
  • Yeah, I was thinking about that too. That works well if you have control over the code that writes to the console. If you don't, you have to use the other way. – Sefe Nov 25 '16 at 11:44
  • 1
    I have updated the post to offer the simpler solution. – Sefe Nov 25 '16 at 11:48
  • Thank you for your response @Sefe I don`t know how to use the WriteLineToScreenAndFil() can you please explain it deeply? –  Nov 25 '16 at 12:31
  • You call it instead of `Console.WriteLine`. So you replace all those occurrences by `WriteLineToScreenAndFile`. – Sefe Nov 25 '16 at 12:44
  • I added the WriteLineToScreenAndFile() method in my program and tried to build(or call that method) my program but it shows "The name 'streamwriter' does not exist in the current context" what i did wrong? –  Nov 26 '16 at 07:25
  • I have written: "assuming your streamwriter variable is accessible". That means the WriteLineToScreenAndFile needs to know of the stream writer. Since it can not know of local variables of other methods, you have to either declare a field in your class and use it instead if the local variable, or you have to add a parameter to the WriteLineTo... method for the stream writer. – Sefe Nov 26 '16 at 07:43
  • I added the field (string streamwriter;) in between class and namespace. when i build my program the exception shows in streamwriter.WriteLine(text); line. That is "'string' does not contain a definition for 'WriteLine' and no extension method 'WriteLine' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)" What i did wrong? –  Nov 26 '16 at 11:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129106/discussion-between-arunald-and-sefe). –  Nov 26 '16 at 13:45