如何保存控制台应用程序的输出

时间:2020-03-05 18:52:55  来源:igfitidea点击:

我需要有关如何让我的Cconsole应用程序通过标准输出向用户显示文本,同时仍然能够在以后访问它的建议。我要实现的实际功能是在程序执行结束时将整个输出缓冲区转储到文本文件中。

我找不到更干净的方法时使用的解决方法是将TextWriter重写为写方法,以使它们都可以写到文件中并调用原始的stdout writer。像这样的东西:

public class DirtyWorkaround {
  private class DirtyWriter : TextWriter {
    private TextWriter stdoutWriter;
    private StreamWriter fileWriter;

    public DirtyWriter(string path, TextWriter stdoutWriter) {
      this.stdoutWriter = stdoutWriter;
      this.fileWriter = new StreamWriter(path);
    }

    override public void Write(string s) {
      stdoutWriter.Write(s);

      fileWriter.Write(s);
      fileWriter.Flush();
    }

    // Same as above for WriteLine() and WriteLine(string),
    // plus whatever methods I need to override to inherit
    // from TextWriter (Encoding.Get I guess).
  }

  public static void Main(string[] args) {
    using (DirtyWriter dw = new DirtyWriter("path", Console.Out)) {
      Console.SetOut(dw);

      // Teh codez
    }
  }
}

看到它一直在写入并刷新文件。我只想在执行结束时这样做,但是我找不到任何访问输出缓冲区的方法。

另外,请原谅上面代码的不正确之处(必须临时编写,对不起;)。

解决方案

回答

我认为方法没有任何问题。

如果我们想要可重用的代码,请考虑实现一个名为MultiWriter的类,或者将两个TextWriter流作为输入并将所有命令,刷新等分配给这些流的类。然后,我们可以执行此文件/控制台操作,但是可以轻松拆分任何输出流。有用!

回答

可能不是我们想要的,只是以防万一。。。显然,PowerShell实现了一个古老的tee命令的版本。正是出于这个目的。所以...如果你有烟,请烟熏他们。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

回答

完美的解决方案是将log4net与控制台添加程序和文件添加程序一起使用。也有许多其他的添加器。它还允许我们在运行时关闭和关闭不同的添加程序。

回答

我想说的是模仿.NET本身使用的诊断(跟踪和调试)。

创建一个"输出"类,该类可以具有遵循文本输出接口的不同类。我们向输出类报告,它会自动将给定的输出发送给我们已添加的类(ConsoleOutput,TextFileOutput,WhateverOutput)。等等。 xslt以获得格式正确的报告?)。

查看Trace Listeners Collection,了解我的意思。

回答

考虑重构应用程序以将用户交互部分与业务逻辑分开。以我的经验,这样的分离对于程序的结构是非常有益的。

对于我们要在此处解决的特定问题,用户交互部分将其行为从" Console.WriteLine"更改为文件I / O变得很简单。

回答

我正在努力实现类似的功能,以捕获发送到控制台的输出并将其保存到日志,同时仍将输出实时传递到普通控制台,以免破坏应用程序(例如,如果它是控制台应用程序) !)。

如果我们仍在尝试通过保存控制台输出(而不是使用日志记录系统仅保存我们真正关心的信息)来用自己的代码执行此操作,那么我认为我们可以避免每次写入后刷新,因为因为我们还重写Flush()并确保它刷新了我们保存的原始stdoutWriterfileWriter。如果应用程序试图将部分行刷新到控制台以立即显示(例如输入提示,进度指示器等),以覆盖常规行缓冲,则需要执行此操作。

如果该方法在控制台输出缓冲时间过长时出现问题,则可能需要确保WriteLine()刷新stdoutWriter(但可能不需要刷新fileWriter,除非调用Flush()覆盖时) 。但是我认为原始的" Console.Out"(实际上是进入控制台)会自动将其缓冲区刷新到换行符上,因此我们不必强制使用它。

我们可能还想重写Close()来(刷新并)关闭fileWriter(也可能是stdoutWriter),但是我不确定这是否真的需要,或者基本TextWriter中的Close()是否会发出Flush()(我们已经覆盖了),并且可能依赖应用程序退出来关闭文件。可以肯定的是,我们应该测试它是否在退出时被刷新了。并且请注意,异常退出(崩溃)可能不会刷新缓冲的输出。如果这是一个问题,则可能需要在换行符上刷新fileWriter,但这是蠕虫可以解决的另一个棘手问题。