Pregunta

Necesito consejos sobre cómo tener mi C# aplicación de consola de texto de la pantalla para el usuario a través de la salida estándar, mientras que todavía siendo capaz de acceder a él más tarde.La real función que me gustaría poner en práctica volcar todo el búfer de salida a un archivo de texto al final de la ejecución del programa.

La solución que yo uso, aunque no creo encontrar un limpiador de enfoque es subclase TextWriter reemplazando los métodos de escritura para escribir a un archivo y llamar a la original stdout escritor.Algo como esto:

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

Ver que se escribe y elimina el archivo todo el tiempo.Me encantaría hacerlo sólo al final de la ejecución, pero no pude encontrar alguna manera de acceder al buffer de salida.

También, excusa imprecisiones con el código anterior (tenía que escribirlo ad hoc, lo siento ;).

¿Fue útil?

Solución

La solución perfecta para esto es el uso de log4net con una consola de appender y un archivo appender.Hay muchas otras appenders disponibles.También le permite a su vez los diferentes appenders off y on en tiempo de ejecución.

Otros consejos

Yo no creo que haya nada malo con su enfoque.

Si usted quería código reutilizable, considere la posibilidad de implementar una clase que se llama MultiWriter o somesuch que toma como entrada dos (o N?) TextWriter los arroyos y distribuye todos los mandamientos, los colores, etc.a los arroyos.A continuación, puede ver este archivo/console cosa, pero apenas como fácilmente se puede dividir cualquier secuencia de salida.Útil!

Probablemente no lo desea, pero sólo en caso de...Al parecer, PowerShell implementa una versión de la venerable tee comando.Lo cual es bastante diseñado para este propósito.Así que...em humo " si los tengo.

Yo diría que imitan los diagnósticos que .NET utiliza (Seguimiento y Depuración).

Crear una "salida" de la clase que puede tener diferentes clases que se adhieran a un texto de la interfaz de salida.Se informe a la salida de clase, automáticamente se envía la salida dada a las clases que se han añadido (ConsoleOutput, TextFileOutput, WhateverOutput)..Y así sucesivamente..Esto también deja abierta para añadir otras "salida" tipos (como xml/xslt para obtener un formato agradable informe?).

Retirar el Seguimiento A Los Oyentes De La Colección a ver a qué me refiero.

Considerar la refactorización su aplicación para separar la interacción del usuario porciones de la lógica de negocio.En mi experiencia, esta separación es muy beneficioso para la estructura de su programa.

Para el problema en particular que usted está tratando de resolver aquí, se hace sencillo para el usuario-interacción de la parte a cambiar su comportamiento de Console.WriteLine a file I/O.

Estoy trabajando en la implementación de una característica similar a la salida de la captura enviada a la Consola y guardarlo en un registro mientras sigue pasando el resultado en tiempo real a la normal de la Consola para que no se rompan la aplicación (por ejemplo.si se trata de una aplicación de consola!).

Si usted todavía está tratando de hacer esto en su propio código por el ahorro de la salida de la consola (en oposición al uso de un sistema de registro para guardar la información que realmente le interesan), creo que se puede evitar el lavado después de cada escritura, siempre y cuando también anular Flush() y asegúrese de que se vuelca a la original stdoutWriter guardó tan bien como tu fileWriter.Quieres hacer esto en caso de que la solicitud está tratando de descarga parcial de la línea a la consola para su visualización inmediata (tales como una entrada rápida, un indicador de progreso, etc), para reemplazar la línea normal de amortiguamiento.

Si ese enfoque tiene problemas con su salida de la consola afectados demasiado largo, usted puede ser que necesite para asegurarse de que WriteLine() vacía stdoutWriter (pero probablemente no es necesario vaciar fileWriter excepto cuando su Flush() anular se llama).Pero yo creo que el original Console.Out (en realidad va a la consola) automáticamente al ras de su búfer en una nueva línea, así que usted no tiene la fuerza.

También puede ser que desee reemplazar Close() a (ras y) cerca de su fileWriter (y probablemente stdoutWriter así), pero no estoy seguro de si es realmente necesario o si un Close() en la base TextWriter emitirá un Flush() (que ya sobrepaso) y usted puede confiar en salir de la aplicación para cerrar el archivo.Probablemente, usted debe probar que se vacían en la salida, para asegurarse de que.Y ser conscientes de que un resultado anormal en la salida (crash) probablemente no vaciar el búfer de salida.Si eso es un problema, flushing fileWriter en la nueva línea puede ser deseable, pero esa es otra complicado lata de gusanos a trabajar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top