Frage

Ich brauche Ratschläge, wie meinen C # Konsolenanwendung Anzeigetext für den Benutzer über die Standardausgabe haben, während es immer noch möglich Zugang später zu sein. Die eigentliche Funktion würde ich umsetzen möchte, ist der gesamten Ausgabepuffer in eine Textdatei am Ende der Programmausführung zu entleeren.

Die Abhilfe, die ich verwende, während ich nicht einen sauberere Ansatz finden, ist TextWriter Überschreiben der Schreibverfahren zu Unterklasse, so dass sie beide in eine Datei schreiben und den ursprünglichen stdout Schriftsteller nennen. So etwas wie folgt aus:

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

Sehen Sie, dass es schreibt und spült die Datei die ganze Zeit. Ich würde es gerne am Ende der Ausführung nur tun, aber ich konnte keine Möglichkeit finden, den Ausgabepuffer zuzugreifen.

Auch Entschuldigung Ungenauigkeiten mit dem obigen Code (hatten, es zu schreiben ad hoc , sorry;).

War es hilfreich?

Lösung

Die perfekte Lösung dafür ist, verwenden log4net mit einer Konsole appender und eine Datei appender. Es gibt viele andere Appen ebenfalls zur Verfügung. Sie können damit auch den verschiedenen Appen aus- und zur Laufzeit drehen.

Andere Tipps

Ich glaube nicht, dass es etwas falsch mit Ihrem Ansatz.

Wenn Sie wieder verwendbaren Code wollten, sollten Sie eine Klasse namens MultiWriter Umsetzung, etc. zu jagen, dass als Eingabe zwei (oder N?) TextWriter Ströme und verteilt alle Verfügungen, Spülungen, usw. zu den Streams. Dann können Sie diese Datei / console Sache tun, aber genauso gut können Sie einen beliebigen Ausgabestrom aufgeteilt. Nützliche!

Wahrscheinlich nicht, was Sie wollen, aber nur für den Fall ... Offenbar Powershell implementiert eine Version des ehrwürdigen tee Befehl . Welche ziemlich viel ist für genau diesen Zweck bestimmt ist. Also ... rauchen 'em, wenn Sie' em.

Ich würde sagen, die Diagnose imitieren, die .NET selbst verwendet (Trace und Debug).

Erstellen Sie eine „Output“ Klasse, die verschiedene Klassen haben kann, die in einer Textausgabeschnittstelle zu halten. Sie berichten an den Ausgabeklasse, sendet er automatisch die zu den Klassen gegebenen Ausgangs Sie (console, TextFileOutput, WhateverOutput) .. hinzugefügt haben und so weiter .. Dies lässt auch Sie öffnen andere „Output“ Typen hinzuzufügen (wie xml / xslt einen schön formatierte Bericht zu bekommen?).

Überprüfen Sie die Hörer Trace-Sammlung , um zu sehen, was ich meine .

Betrachten Sie Ihre Anwendung Refactoring die Benutzer-Interaktion Abschnitte von der Geschäftslogik zu trennen. Nach meiner Erfahrung, eine solche Trennung ist sehr vorteilhaft für die Struktur des Programms.

Für das spezielle Problem, das Sie versuchen, hier zu lösen, wird es einfach für den Benutzer-Interaktion Teil seines Verhalten von Console.WriteLine zu ändern E / A-Datei.

Ich arbeite eine ähnliche Funktion bei der Umsetzung Ausgabe an die Konsole gesendet zu erfassen und in ein Protokoll speichern, während immer noch die Ausgabe in Echtzeit auf die normale Konsole vorbei, damit es nicht die Anwendung brechen (z. B. wenn es eine Konsolenanwendung!).

Wenn Sie immer noch versuchen, dies in Ihrem eigenen Code zu tun, indem Sie die Ausgabe der Konsole speichern (im Gegensatz eines Logging-Systems zur Verwendung von nur die Informationen zu speichern über Sie wirklich interessieren), ich glaube, Sie den Flush vermeiden können nach jedem schreiben , solange Sie auch Flush () außer Kraft setzen und sicherstellen, dass es spült die ursprüngliche stdoutWriter Sie sowie Ihre fileWriter gespeichert. Sie wollen dies die Anwendung zu tun, falls versucht, eine Teil-Zeile auf die Konsole zur sofortigen Anzeige (wie zum Beispiel einer Eingabeaufforderung, eine Fortschrittsanzeige, usw.) zu spülen, die normale Line-Pufferung außer Kraft zu setzen.

Wenn dieser Ansatz Probleme mit Ihrer Konsole ausgegeben hat zu lange zwischengespeichert werden, müssen Sie möglicherweise sicherstellen, dass Writeline () leert stdoutWriter (aber wahrscheinlich nicht braucht fileWriter außer zu spülen, wenn der Flush () Überschreiben genannt wird). Aber ich würde denken, dass die ursprüngliche Console.Out (tatsächlich an die Konsole zu gehen) würde automatisch den Puffer auf eine neue Zeile spülen, so sollten Sie es nicht zwingen müssen.

Sie mögen vielleicht auch Close () bis (Flush und) schließen Sie Ihren fileWriter (und wahrscheinlich stdoutWriter auch) außer Kraft zu setzen, aber ich bin nicht sicher, ob das wirklich gebraucht wird, oder wenn ein Close () in dem Basistextwriter ausgeben würde ein Flush () (die Sie bereits würde außer Kraft setzen), und Sie können auf das Beenden der Anwendung verlassen Ihre Datei zu schließen. Sie sollen wahrscheinlich testen, dass es bei der Ausfahrt gespült wird, um sicher zu sein. Und sich bewusst sein, dass ein abnormaler Ausgang (Absturz) wahrscheinlich nicht gepufferte Ausgang spülen wird. Wenn das ein Problem ist, sein kann wünschenswert fileWriter auf Newline Spülung, aber das ist eine andere heikle Dose Würmer heraus zu arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top