[英]How to write Console ouput to both console and file in C#?
我有一個簡單的控制台應用程序,我在很多地方都使用了Console.WriteLine
來向用戶顯示正在執行的活動。 但是,最后我想將所有控制台 output 也保存到日志文件中。 目前,我有這樣的事情:
if (!Directory.Exists(LOG_DIRECTORY)) {
Directory.CreateDirectory(LOG_DIRECTORY);
}
long ticks = DateTime.Now.Ticks;
string logFilename = ticks.ToString() + ".txt";
string filePath = Directory.GetCurrentDirectory() + "\\" + LOG_DIRECTORY + "\\" + logFilename;
FileStream ostream = null;
StreamWriter writer = null;
TextWriter oldOut = Console.Out;
try
{
ostream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
writer = new StreamWriter(ostream);
}
catch (Exception ex)
{
Console.WriteLine("Cannot open {0} for writing.", logFilename);
Console.WriteLine(ex.Message);
return;
}
Console.SetOut(writer);
Console.WriteLine("{0}", Directory.GetCurrentDirectory());
Console.SetOut(oldOut);
writer.Close();
ostream.Close();
Console.WriteLine("\n\nDone!");
關鍵是這會將內容直接打印到文件中,而控制台中不會打印任何內容。 有沒有辦法解決這個問題? 請注意,我需要將Console.WriteLine
output 直接實時寫入控制台,而對於寫入日志文件,可以在程序結束時完成,幾乎所有其他事情都完成了。
您可以創建自己的組件以寫入多個輸出,也可以使用NLog等日志記錄工具。 這可以配置為在<targets>
部分你有類似的東西;
<target name="debugger" xsi:type="Debugger" layout="${level}>${message} (${exception:format=ToString})"/>
<target name="console" xsi:type="ColoredConsole" layout="${date:format=dd-MM-yyyy HH\:mm\:ss} - ${message}" />
<target name="FullCSVFile" xsi:type="File" fileName="${specialfolder:folder=LocalApplicationData}\YourApp\YourApp-${date:format=yyyy-MM-dd}.csv">
<layout xsi:type="CsvLayout">
<column name="Index" layout="${counter}" />
<column name="ThreadID" layout="${threadid}" />
<column name="Time" layout="${longdate}" />
<column name="Severity" layout="${level:uppercase=true}" />
<column name="Location" layout="${callsite:className=False:fileName=True:includeSourcePath=False:methodName=False}" />
<column name="Detail" layout="${message}" />
<column name="Exception" layout="${exception:format=ToString}" />
</layout>
</target>
然后在rules
部分,你會有;
<logger name="*" minlevel="Debug" writeTo="console" />
<logger name="*" minlevel="Debug" writeTo="debugger" />
<logger name="*" minlevel="Debug" writeTo="FullCSVFile" />
要實際執行寫操作,您的C#代碼中將包含以下內容:
// at a class level;
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
// later in code that writes to both targets...
_logger.Info("Something happened!");
如何在變量中保存控制台輸出,如string array
或List<string>
? 然后執行File.WriteAllText(filepath, consoleOutputArray);
我的意思是這樣的:
class Program
{
static void Main(string[] args)
{
List<string> textStorage = new List<string>();
string exampleData = "Ford Mustang";
Console.WriteLine(exampleData);
SaveOutput(ref textStorage, exampleData);
System.IO.File.WriteAllLines(@"C://Desktop//MyFolder", textStorage);
}
public static void SaveOutput(ref List<string> textStorage, string output)
{
textStorage.Add(output);
}
}
每個控制台輸出后,將輸出存儲在列表中,並在程序結束時更新包含詳細信息的日志。
var list = new List<string>;
string xyz = "message";
Console.WriteLine(xyz);
list.add(xyz);
foreach (object o in list)
{
StreamWriter sw = null;
String Logfile = "C:\ExceptionLog.txt";
if (!System.IO.File.Exists(LogFile))
{
sw = File.CreateText(LogFile);
}
else
{
sw = File.AppendText(@"C:\ExceptionLog.txt");
}
sw.WriteLine(o);
sw.Close();
}
我在簡單的場景中使用這樣的東西 - 當我正在制作原型或研究某些東西並且不想擔心意外丟失控制台 output 時。
// run this at application start
using var multiWriter = new MultiTextWriter(File.CreateText("my_log_file"), Console.Out);
Console.SetOut(multiWriter);
public class MultiTextWriter : TextWriter
{
private readonly TextWriter[] _writers;
public MultiTextWriter(params TextWriter[] writers)
{
_writers = writers;
}
// abstract in parent; most of the time you don't need it, though
// xml stuff needs it, so you may have to implement it
public override Encoding Encoding => throw new NotImplementedException();
// technically I think this is the only thing you need to override
public override void Write(char value)
{
for (var index = 0; index < _writers.Length; index++)
{
_writers[index].Write(value);
}
}
public override void Write(string? value)
{
for (var index = 0; index < _writers.Length; index++)
{
_writers[index].Write(value);
}
}
protected override void Dispose(bool disposing)
{
for (var index = 0; index < _writers.Length; index++)
{
_writers[index].Dispose();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.