2008-09-14 7 views
10

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

항상 파일에 쓰고 플러시한다는 것을 확인하십시오. 나는 실행의 끝에서만 그것을하고 싶지만 출력 버퍼에 접근하는 방법을 찾을 수 없었다.

또한 위 코드를 사용하여 부정확성을 설명하십시오 (ad hoc, 죄송합니다.).

답변

5

log4net을 콘솔 첨부 자 및 파일 첨부 자와 함께 사용하면됩니다. 다른 많은 appender도 사용할 수 있습니다. 또한 런타임에 다른 appenders를 켜고 끌 수 있습니다.

+0

아주 좋은 아이디어! 실제로 필요한 것은 로거입니다. 그렇게하면 사용자에게 표시되는 것보다 훨씬 많은 정보를 저장할 수 있습니다 (버그는 훨씬 적습니다). 여러 방면에서 가장 좋은 해결책은 문제의 외부인으로부터 오는 다른 접근 방식에서 비롯된 것입니다. –

+2

필자는이 경우 시스템에 필요한 기능을 추가하기 위해 작업량이 적을 때 타사 라이브러리를 사용하는 것이 과도하다고 생각합니다. – Wedge

+3

나는 log4net이 여기에 걸릴 상당한 의존성에 동의한다. –

4

나는 당신의 접근 방식에 문제가 있다고 생각하지 않습니다.

코드를 재사용하고자하는 경우 MultiWriter 클래스를 구현하거나 두 입력 (또는 N?) TextWriter 스트림을 가져 와서 모든 스트림, 플러시 등을 해당 스트림으로 분배하는 것을 고려하십시오. 그러면이 파일/콘솔 작업을 수행 할 수 있지만 출력 스트림을 쉽게 분할 할 수 있습니다. 유능한!

+0

내 접근 방식의 문제점은 파일을 열어두고 항상 비우는 것입니다. 그리고 필자는 모든 글을 쓸 때마다 파일을 열고 닫는 것이 번거로울 것이라고 생각합니다. MultiWriter에 대한 아이디어는 매우 영리합니다. :) –

1

아마 당신이 원하는 것은 아니지만 단지 ... PowerShell implementstee 명령의 버전입니다. 이 목적은 정확히이 목적을위한 것입니다. 그래서 ... 담배를 피우면 되 잖아.

1

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

텍스트 출력 인터페이스를 준수하는 여러 클래스를 가질 수있는 "출력"클래스를 만듭니다. 출력 클래스에보고하면 추가 한 클래스 (ConsoleOutput, TextFileOutput, WhateverOutput)에 주어진 출력을 자동으로 보냅니다. 이렇게하면 다른 "출력"유형 (예 : xml/멋지게 형식화 된 보고서를 얻으려면 xslt?).

내 뜻을 확인하려면 Trace Listeners Collection을 확인하십시오.

0

응용 프로그램을 리팩터링하여 사용자 상호 작용 부분을 비즈니스 논리와 분리하는 것을 고려하십시오. 내 경험에 비추어 볼 때 그러한 분리는 프로그램의 구조에 매우 유익합니다.

여기에서 해결하고자하는 특정 문제에 대해 사용자 상호 작용 부분이 Console.WriteLine에서 파일 I/O로 동작을 변경하는 것은 간단합니다.

0

비슷한 기능을 구현하여 Console에 보낸 출력을 캡처하고 로그에 저장하면서 실시간으로 출력을 일반 콘솔로 전달하면서 응용 프로그램을 중단시키지 않습니다 (예 : if 그것은 콘솔 응용 프로그램입니다!).

콘솔 출력을 저장하여 여전히 자신의 코드에서이 작업을 수행하려는 경우 (로깅 시스템을 사용하여 실제로 신경 써야 할 정보 만 저장하는 것과 반대), 각각의 작업 이후에 플러시를 피할 수 있다고 생각합니다. 쓰기, 당신은 또한 플러시()를 재정의하고 당신이 fileWriter뿐만 아니라 저장된 stdoutWriter 원래 플러시되었는지 확인하십시오. 응용 프로그램이 즉각적인 표시 (입력 프롬프트, 진행 표시기 등)를 위해 콘솔의 부분 행을 플러시하여 정상적인 행 버퍼링을 무시하려는 경우이 작업을 수행하려고합니다.

콘솔 출력이 너무 오래 버퍼링되는 데 문제가있는 경우 WriteLine()을 stdoutWriter으로 플러시해야합니다 (플러시() 재정의가 호출 될 때를 제외하고는 fileWriter을 플러시하지 않아도됩니다) . 하지만 원래의 Console.Out (실제로 콘솔로 간다)이 자동으로 개행 할 때 버퍼를 비울 것이라고 생각 했으므로 강제로하지 않아도됩니다.

또한 fileWriter (및 아마도 stdoutWriter)을 닫기 (닫기)를 재정의하고 싶을 수도 있습니다. 그러나 실제로 필요한지 또는 기본 TextWriter의 Close()가 Flush() (이미 재정의)를 실행하면 응용 프로그램 종료를 사용하여 파일을 닫을 수 있습니다. 아마 출구에서 빠져 나오는지 테스트해야합니다. 비정상적인 종료 (충돌)가 버퍼링 된 출력을 플러시하지 않을 가능성이 있습니다. 그게 문제라면, 줄 바꿈에 fileWriter을 내뿜는 것이 바람직 할 수도 있지만, 그것은 또 다른 까다로운 웜이 될 수 있습니다.

관련 문제