如何在C#中一次将控制台输出到多个流?

时间:2012-06-06 16:20:16

标签: c# .net-4.0 stream

我有一个程序,它接受控制台输出并将其写入日志文件,但它不再显示在控制台窗口中。有没有办法将它保留在窗口中,但也将它写入日志文件?

更新

appLogStream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
TextWriter logtxtWriter = Console.Out;
logstrmWriter = new StreamWriter(appLogStream);
if(!console) Console.SetOut(logstrmWriter);
logstrmWriter.AutoFlush = true;
Console.WriteLine("Started at " + DateTime.Now);

console是类中的常量集。它基本上告诉它是否正在使用控制台窗口(如果不在控制台中,则不会调用readline等。)

那么有没有办法写入控制台和文件?

3 个答案:

答案 0 :(得分:1)

您可以直接读取该流记录并打印出来。

如果你将输出流分配给outfile的输入流,这取决于你的代码,如果你把内容读到一个应该更容易的缓冲区,这可能会有点困难。


关于您的更新我建议您使用自定义日志记录功能交换所有Console,例如MyLogger的一个实例(下面的代码)。它将您的输出写入控制台和日志文件。

class MyLogger {
    private FileStream appLogStream;

    public MyLogger() {
        appLogStream = new FileStream(logFile, FileMode.Append, FileAccess.Write,
                                      FileShare.Read);
        appLogStream.WriteLine("Started at " + DateTime.Now);
    }

    public Write(string msg) {
        Console.Write(msg);
        appLogStream.Write(msg);
    }

    public WriteLine(string msg) {
        Console.WriteLine(msg);
        appLogStream.WriteLine(msg);
    }
}

答案 1 :(得分:1)

我认为你可以这样做:

 public class ConsoleDecorator : TextWriter
{
    private TextWriter m_OriginalConsoleStream;

    public ConsoleDecorator(TextWriter consoleTextWriter)
    {
        m_OriginalConsoleStream = consoleTextWriter;
    }

    public override void WriteLine(string value)
    {
        m_OriginalConsoleStream.WriteLine(value);

        // Fire event here with value
    }


    public static void SetToConsole()
    {
        Console.SetOut(new ConsoleDecorator(Console.Out));
    }
}

您必须通过调用ConsoleDecorator.SetToConsole()来“注册”包装器; 之后,每个Console.WriteLine调用都将转到自定义方法,您可以在那里触发事件并获取在其他位置写入的文本(例如,记录日志)。

如果您想要使用这种方式,则必须使该类成为单例,然后您可以访问其他类的偶数注册(当偶数被触发时应该写入日志文件)

答案 2 :(得分:0)

调用Console.SetOut时,指定Console应写入的位置。如果你没有(即通常使用Console的方式),并且你调用Console.Write,它会检查它是否有输出编写器,如果没有,则设置为

   stream = OpenStandardOutput(256);

然后

        Encoding encoding = Encoding.GetEncoding((int) Win32Native.GetConsoleOutputCP());
        writer = TextWriter.Synchronized(new StreamWriter(stream, encoding, 256, false) { HaveWrittenPreamble = true, AutoFlush = true });

所以你应该能够做你现在正在做的事情,并且如果你也希望将所有内容都标记为标准输出,就像你没有重定向控制台一样,你可以使用你自己打开的流创建自己的编写器Console.OpenStandardOutput方法。该代码中使用的Win32Native是内部的,因此您无权访问它,但您可以使用Console.OutputEncoding检索它正在使用的编码。

您还可以尝试使用Console.Out属性在调用SetOut之前获取并挂起标准输出TextWriter。然后你可以用它来回显标准输出。