문제

C# 콘솔 응용 프로그램에서 표준 출력을 통해 사용자에게 텍스트를 표시하는 동시에 나중에 액세스할 수 있게 하는 방법에 대한 조언이 필요합니다.실제로 구현하고 싶은 기능은 프로그램 실행이 끝날 때 전체 출력 버퍼를 텍스트 파일로 덤프하는 것입니다.

더 깔끔한 접근 방식을 찾지 못할 때 사용하는 해결 방법은 하위 클래스를 만드는 것입니다. TextWriter 쓰기 방법을 재정의하여 파일에 쓰고 원본 stdout 작성기를 호출합니다.이 같은:

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
    }
  }
}

항상 파일에 쓰고 플러시하는지 확인하세요.실행이 끝날 때만 하고 싶지만 출력 버퍼에 액세스할 수 있는 방법을 찾을 수 없습니다.

또한 위 코드의 부정확성을 양해해 주시기 바랍니다. 애드 혹, 죄송합니다 ;).

도움이 되었습니까?

해결책

이에 대한 완벽한 솔루션은 다음을 사용하는 것입니다. log4net 콘솔 어펜더와 파일 어펜더를 사용합니다.다른 많은 어펜더도 사용할 수 있습니다.또한 런타임에 다른 어펜더를 끄거나 켤 수도 있습니다.

다른 팁

나는 당신의 접근 방식에 문제가 없다고 생각합니다.

재사용 가능한 코드를 원한다면 다음과 같은 클래스를 구현하는 것을 고려해보세요. MultiWriter 또는 입력 2(또는 N?)로 사용되는 것 TextWriter 모든 영장, 플러시 등을 스트리밍하고 배포합니다.그 스트림에.그런 다음 이 파일/콘솔 작업을 수행할 수 있지만 마찬가지로 쉽게 모든 출력 스트림을 분할할 수 있습니다.유용한!

아마도 당신이 원하는 것은 아닐 것입니다. 그러나 만약을 대비해서...보기에, PowerShell 구현 존경받는 버전 tee 명령.정확히 이 목적을 위해 의도된 것입니다.그래서...있으면 담배를 피우세요.

.NET 자체에서 사용하는 진단(추적 및 디버그)을 모방한다고 말하고 싶습니다.

텍스트 출력 인터페이스를 준수하는 다양한 클래스를 가질 수 있는 "출력" 클래스를 만듭니다.출력 클래스에 보고하면 추가한 클래스(ConsoleOutput, TextFileOutput, EverythingOutput)에 제공된 출력이 자동으로 전송됩니다.등등..이는 또한 다른 "출력" 유형(예: 멋진 형식의 보고서를 얻기 위한 xml/xslt?)을 추가할 수 있도록 열어줍니다.

확인해 보세요 추적 수신기 컬렉션 무슨 뜻인지 알아보려고요.

비즈니스 로직에서 사용자 상호 작용 부분을 분리하려면 애플리케이션을 리팩터링하는 것이 좋습니다.내 경험상 이러한 분리는 프로그램 구조에 매우 유익합니다.

여기서 해결하려는 특정 문제의 경우 사용자 상호 작용 부분에서 동작을 변경하는 것이 간단해집니다. Console.WriteLine I/O를 파일화합니다.

저는 콘솔로 전송된 출력을 캡처하여 로그에 저장하는 동시에 출력을 일반 콘솔에 실시간으로 전달하여 응용 프로그램이 중단되지 않도록 하는 유사한 기능을 구현하는 중입니다(예:콘솔 애플리케이션인 경우!).

콘솔 출력을 저장하여 자신의 코드에서 이 작업을 계속 시도하고 있다면(로깅 시스템을 사용하여 정말로 관심 있는 정보만 저장하는 것과 반대), 각 쓰기 후 플러시를 피할 수 있다고 생각합니다. Flush()도 재정의하고 원본을 플러시하는지 확인하세요. stdoutWriter 너도 저장했고 fileWriter.애플리케이션이 즉각적인 표시(예: 입력 프롬프트, 진행률 표시기 등)를 위해 부분 라인을 콘솔에 플러시하여 일반 라인 버퍼링을 재정의하려는 경우에 이 작업을 수행하려고 합니다.

해당 접근 방식에 콘솔 출력이 너무 오래 버퍼링되는 문제가 있는 경우 WriteLine()이 플러시되는지 확인해야 할 수도 있습니다. stdoutWriter (그러나 아마도 플러시할 필요는 없을 것입니다. fileWriter Flush() 재정의가 호출되는 경우는 제외).하지만 내 생각엔 원본이 Console.Out (실제로 콘솔로 이동) 개행 시 자동으로 버퍼를 플러시하므로 강제로 실행할 필요가 없습니다.

Close()를 재정의하여 (플러시하고) 닫을 수도 있습니다. fileWriter (아마도 stdoutWriter 마찬가지로), 그러나 이것이 실제로 필요한지 또는 기본 TextWriter의 Close()가 Flush()(이미 재정의함)를 실행하고 응용 프로그램 종료를 사용하여 파일을 닫을 수 있는지 확실하지 않습니다.확실히 하려면 종료 시 플러시되는지 테스트해야 합니다.그리고 비정상적인 종료(충돌)로 인해 버퍼링된 출력이 플러시되지 않을 가능성이 높습니다.그게 문제라면 플러싱을 하세요 fileWriter 개행 문자를 사용하는 것이 바람직할 수 있지만 이는 해결해야 할 또 다른 까다로운 웜 캔입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top