6

如果我们编译以下代码并运行生成的应用程序,我们将通过输入我们的名称、按 enter 并按任意键退出来与之交互。所有这些操作都在控制台窗口上完成。

using System;

namespace HelloWorld
{
    class Program
    {

        static void Main(string[] args)
        {
            Console.Write("Enter your name: ");
            var name = Console.ReadLine();
            Console.WriteLine("Your name is {0} ", name);
            Console.ReadKey();

        }
    }
}

是否可以将所有这些操作保存到文本文件中,以便我可以将其用作日志?

编辑:

我应该解释一下真实情况。我正在写一本关于 C# 的书。我想避免将控制台窗口的屏幕截图附加到书中,因为我想让我的书的文件大小尽可能小。相反,我想将显示控制台窗口内容的文本文件附加到书中。添加额外的代码(用于创建文本文件)会使代码示例复杂化,进而使读者感到困惑。

4

4 回答 4

2

好的,所以这里的想法是更改控制台输入和输出的读取器/写入器,以执行它们之前所做的操作,同时写入日志文件。我创建了一个 Log 类,它可能应该被扩展以便将文件名/路径作为参数,但重要的是要有一个这样才能同步输出流。

public class Log
{
    private StreamWriter output;
    public Log()
    {
        output = new StreamWriter(File.OpenWrite("output.txt"));

    }
    public void Write(char c)
    {
        lock (output)
        {
            output.Write(c);
        }
    }
    public void Close()
    {
        output.Close();
    }
}

public class MyConsoleOutput : TextWriter
{
    private TextWriter standard;
    private Log log;

    public MyConsoleOutput(TextWriter standard, Log log)
    {
        this.standard = standard;
        this.log = log;
    }

    public override void Write(char value)
    {
        standard.Write(value);
        log.Write(value);
    }

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

    protected override void Dispose(bool disposing)
    {
        standard.Dispose();
    }
}

public class MyConsoleInput : TextReader
{
    private TextReader standard;
    private Log log;
    public MyConsoleInput(TextReader standard, Log log)
    {
        this.standard = standard;
        this.log = log;
    }

    public override int Peek()
    {
        return standard.Peek();
    }


    public override int Read()
    {
        int result = standard.Read();
        log.Write((char)result);
        return result;
    }
    protected override void Dispose(bool disposing)
    {
        standard.Dispose();
    }
}

现在我们已经创建了这些类,我们将在开始时执行以下操作Main

Log log = new Log();
Console.SetOut(new MyConsoleOutput(Console.Out, log));
Console.SetIn(new MyConsoleInput(Console.In, log));

我们在结尾处也需要这个Main

log.Close();

这是一个有点快速和肮脏的写作。如果您在生产中使用它,您可能需要更改很多类/方法名称。

于 2012-05-24T18:29:49.520 回答
1

没有什么会自动“隐藏”您的控制台 IO,因此您必须自己执行此操作。话虽这么说,打开一个文本文件并写任何你想要的东西是相当容易的。

在您的情况下,只需打开一个文本文件,并在您写入控制台并根据需要从控制台读取时将信息写入其中。有关详细信息,请参阅 MSDN 的如何:写入文本文件

于 2012-05-24T18:02:21.530 回答
1

您可以使用 aStreamWriter输出您通过以下方式捕获的内容Console

using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\ProgramOutput.txt", true))
        {
            file.WriteLine(name);
        }  
于 2012-05-24T18:03:24.120 回答
0

这个例子可以帮助你:

Console.WriteLine("Hello World");
FileStream fs = new FileStream("Test.txt", FileMode.Create);
// First, save the standard output.
TextWriter tmp = Console.Out;
StreamWriter sw = new StreamWriter(fs);
Console.SetOut(sw);
Console.WriteLine("Hello file");
Console.SetOut(tmp);
Console.WriteLine("Hello World");
sw.Close();

阅读更多: http: //msdn.microsoft.com/ru-ru/library/system.console.setin.aspx,http : //msdn.microsoft.com/ru-ru/library/system.console.setout。 aspx, http: //msdn.microsoft.com/en-us/library/system.console.in.aspx,http : //msdn.microsoft.com/ru-ru/library/system.console.out.aspx

于 2012-05-24T18:25:54.213 回答