leer - guardar datos en un bloc de notas c#
Cómo guardar el resultado de una aplicación de consola (6)
Necesito consejos sobre cómo hacer que mi aplicación de consola C # muestre el texto al usuario a través de la salida estándar mientras aún puedo acceder a él más adelante. La característica real que me gustaría implementar es descargar todo el buffer de salida a un archivo de texto al final de la ejecución del programa.
La solución alternativa que uso mientras no encuentro un enfoque más limpio es subclasificar TextWriter
anulando los métodos de escritura para que ambos escriban en un archivo y llamen al escritor original de stdout. 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 escribe y vacía el archivo todo el tiempo. Me encantaría hacerlo solo al final de la ejecución, pero no pude encontrar ninguna forma de acceder al buffer de salida.
Además, justifique las imprecisiones con el código anterior (tuvo que escribirlo ad hoc , lo siento;).
No creo que haya nada de malo en tu enfoque.
Si quería un código reutilizable, considere implementar una clase llamada MultiWriter
o somesuch que tome como entrada dos (o N?) TextWriter
y distribuya todas las escrituras, vaciados, etc. a esas transmisiones. Entonces puede hacer esto de archivo / consola, pero igual de fácil puede dividir cualquier flujo de salida. ¡Útil!
Probablemente no sea lo que quieras, pero por las dudas ... Aparentemente, PowerShell implementa una versión del venerable comando tee
. Que es más o menos exactamente para este propósito. Entonces ... fóllalos si los tienes.
Considere refactorizar su aplicación para separar las porciones de interacción del usuario de la lógica comercial. En mi experiencia, tal separación es bastante beneficiosa para la estructura de su programa.
Para el problema particular que está tratando de resolver aquí, resulta sencillo para la parte de interacción del usuario cambiar su comportamiento de Console.WriteLine
a file I / O.
La solución perfecta para esto es usar log4net con un appender de consola y un appender de archivos. También hay muchos otros apéndices disponibles. También le permite apagar y encender los diferentes apéndices en tiempo de ejecución.
Yo diría que imitan los diagnósticos que .NET usa (Trace y Debug).
Cree una clase de "salida" que pueda tener diferentes clases que se adhieran a una interfaz de salida de texto. Usted informa a la clase de salida, envía automáticamente la salida dada a las clases que ha agregado (ConsoleOutput, TextFileOutput, WhateverOutput) ... Y así sucesivamente ... Esto también lo deja abierto para agregar otros tipos de "salida" (como xml / xslt para obtener un informe muy formateado?).
Mira la Colección Trace Listeners para ver a qué me refiero.
Estoy trabajando en la implementación de una función similar para capturar la salida enviada a la consola y guardarla en un registro mientras paso la salida en tiempo real a la consola normal para que no rompa la aplicación (por ejemplo, si es una aplicación de consola) !).
Si todavía está tratando de hacer esto en su propio código guardando la salida de la consola (en lugar de usar un sistema de registro para guardar solo la información que realmente le importa), creo que puede evitar el color después de cada escritura, siempre y cuando ya que también anula Flush () y se asegura de que stdoutWriter
el stdoutWriter
original que guardó, así como su fileWriter
. Desea hacer esto en caso de que la aplicación intente vaciar una línea parcial a la consola para su visualización inmediata (como un mensaje de entrada, un indicador de progreso, etc.), para anular el almacenamiento en línea normal.
Si ese enfoque tiene problemas con la salida de la consola demasiado larga, es posible que deba asegurarse de que WriteLine () stdoutWriter
(pero probablemente no necesite vaciar fileWriter
excepto cuando se fileWriter
su anulación de Flush ()). Pero creo que la Console.Out
original (que en realidad va a la consola) vaciará automáticamente su buffer en una nueva línea, por lo que no debería tener que forzarlo.
También es posible que desee anular Close () para (vaciar y) cerrar su fileWriter
(y probablemente también stdoutWriter
), pero no estoy seguro de si eso es realmente necesario o si un Close () en el TextWriter base emitiría un Flush ( ) (que ya anularía) y puede confiar en la salida de la aplicación para cerrar su archivo. Probablemente deberías probar que se enjuaga al salir, para estar seguro. Y tenga en cuenta que una salida anormal (falla) probablemente no purgue la salida almacenada en el búfer. Si eso es un problema, puede ser deseable enjuagar fileWriter
en newline, pero esa es otra lata de gusanos difícil de resolver.