[c#] 콘솔 출력을 파일로 미러링

C # 콘솔 애플리케이션에서 콘솔 출력을 텍스트 파일에 미러링하는 현명한 방법이 있습니까?

현재 저는 로그 메서드 Console.WriteLine와 둘 다에 동일한 문자열을 전달하고 InstanceOfStreamWriter.WriteLine있습니다.



답변

이것은 좀 더 많은 일이 될 수 있지만 나는 다른 방향으로 갈 것입니다.

TraceListener콘솔 용과 로그 파일 용으로 인스턴스화 하십시오. 그 후에 Trace.Write코드에서 Console.Write. 나중에 로그 또는 콘솔 출력을 제거하거나 다른 로깅 메커니즘을 연결하는 것이 더 쉬워집니다.

static void Main(string[] args)
{
    Trace.Listeners.Clear();

    TextWriterTraceListener twtl = new TextWriterTraceListener(Path.Combine(Path.GetTempPath(), AppDomain.CurrentDomain.FriendlyName));
    twtl.Name = "TextLogger";
    twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;

    ConsoleTraceListener ctl = new ConsoleTraceListener(false);
    ctl.TraceOutputOptions = TraceOptions.DateTime;

    Trace.Listeners.Add(twtl);
    Trace.Listeners.Add(ctl);
    Trace.AutoFlush = true;

    Trace.WriteLine("The first line to be in the logfile and on the console.");
}

내가 기억할 수있는 한, 애플리케이션 구성에서 리스너를 정의하여 빌드를 건드리지 않고도 로깅을 활성화하거나 비활성화 할 수 있습니다.


답변

이것은 입력을 파일과 콘솔 모두로 리디렉션 할 수 있도록 TextWriter를 하위 클래스로 만드는 간단한 클래스입니다.

이렇게 사용하세요

  using (var cc = new ConsoleCopy("mylogfile.txt"))
  {
    Console.WriteLine("testing 1-2-3");
    Console.WriteLine("testing 4-5-6");
    Console.ReadKey();
  }

수업은 다음과 같습니다.

class ConsoleCopy : IDisposable
{

  FileStream fileStream;
  StreamWriter fileWriter;
  TextWriter doubleWriter;
  TextWriter oldOut;

  class DoubleWriter : TextWriter
  {

    TextWriter one;
    TextWriter two;

    public DoubleWriter(TextWriter one, TextWriter two)
    {
      this.one = one;
      this.two = two;
    }

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

    public override void Flush()
    {
      one.Flush();
      two.Flush();
    }

    public override void Write(char value)
    {
      one.Write(value);
      two.Write(value);
    }

  }

  public ConsoleCopy(string path)
  {
    oldOut = Console.Out;

    try
    {
      fileStream = File.Create(path);

      fileWriter = new StreamWriter(fileStream);
      fileWriter.AutoFlush = true;

      doubleWriter = new DoubleWriter(fileWriter, oldOut);
    }
    catch (Exception e)
    {
      Console.WriteLine("Cannot open file for writing");
      Console.WriteLine(e.Message);
      return;
    }
    Console.SetOut(doubleWriter);
  }

  public void Dispose()
  {
    Console.SetOut(oldOut);
    if (fileWriter != null)
    {
      fileWriter.Flush();
      fileWriter.Close();
      fileWriter = null;
    }
    if (fileStream != null)
    {
      fileStream.Close();
      fileStream = null;
    }
  }

}


답변

log4net을 확인하십시오 . log4net을 사용하면 단일 로그 문으로 두 위치에 로그 메시지를 출력 할 수있는 콘솔 및 파일 어 펜더를 설정할 수 있습니다.


답변

>명령을 사용하여 출력을 파일로 리디렉션 할 수 없습니까 ?

c:\>Console.exe > c:/temp/output.txt

미러링해야하는 경우 tee출력을 파일로 분할 하는 win32 버전을 찾을 수 있습니다 .

PowerShell에서 를 실행 하려면 /superuser/74127/tee-for-windows 를 참조 하십시오.


답변

TextWriter 클래스의 하위 클래스를 만든 다음 Console.SetOut 메서드를 사용하여 해당 인스턴스를 Console.Out에 할당 할 수 있습니다. 특히 로그 메서드의 두 메서드에 동일한 문자열을 전달하는 것과 동일한 작업을 수행합니다.

또 다른 방법은 자신의 콘솔 클래스를 선언하고 using 문을 사용하여 클래스를 구분할 수 있습니다.

using Console = My.Very.Own.Little.Console;

표준 콘솔에 액세스하려면 다음이 필요합니다.

global::Console.Whatever


답변

편집 :이 방법은 타사 패키지에서 가져온 콘솔 정보를 리디렉션 할 수있는 가능성을 제공합니다. WriteLine 메서드를 재정의하는 것은 내 상황에 적합하지만 타사 패키지에 따라 다른 Write 메서드를 재정의해야 할 수도 있습니다.

먼저 CombinedWriter와 같이 StreamWriter에서 고유 한 새 클래스를 만들어야합니다.

그런 다음 Console.Out으로 CombinedWriter의 새 인스턴스를 초기화합니다.

마지막으로 Console.SetOut에 의해 콘솔 출력을 새 클래스의 인스턴스로 리디렉션 할 수 있습니다.

다음 코드는 새로운 수업이 저에게 효과적입니다.

public class CombinedWriter : StreamWriter
{
    TextWriter console;
    public CombinedWriter(string path, bool append, Encoding encoding, int bufferSize, TextWriter console)
        :base(path, append, encoding, bufferSize)
    {
        this.console = console;
        base.AutoFlush = true; // thanks for @konoplinovich reminding
    }
    public override void WriteLine(string value)
    {
        console.Write(value);
        base.WriteLine(value);
    }
}


답변

Log4net 이이를 수행 할 수 있습니다. 다음과 같이 작성합니다.

logger.info("Message");

구성에 따라 출력물이 콘솔, 파일 또는 둘 다로 이동할지 여부가 결정됩니다.