將C#的Console.Write同步到控制檯和log檔案輸出
阿新 • • 發佈:2020-12-16
將C#的Console.Write同步到控制檯和log檔案輸出
日常編寫小工具時,使用Console.Write
會把日誌輸出到控制檯中,這便於在執行過程檢視日誌,但如果日誌過多,或者希望能對日誌進行查詢,複製操作時,在控制檯中就不方便操作了,這時就希望能把日誌輸出到log檔案中,通過Console.SetOut
可以將輸出重定向到檔案,不過這樣就不方便在執行時檢視日誌進度。有沒有辦法可以把日誌同步輸出到控制檯和log檔案中呢?
參考StackOverflow的一個回答,其實原理很簡單,就是我們自己實現一個TextWriter
,它接受一個檔案和原Console的輸出流,然後將輸出重定向到這個TextWriter
程式碼如下:
public class ConsoleCopy : IDisposable
{
private FileStream m_FileStream;
private StreamWriter m_FileWriter;
private readonly TextWriter m_DoubleWriter;
private readonly TextWriter m_OldOut;
private class DoubleWriter : TextWriter
{
private TextWriter m_One;
private TextWriter m_Two;
public DoubleWriter(TextWriter one, TextWriter two)
{
m_One = one;
m_Two = two;
}
public override Encoding Encoding
{
get { return m_One.Encoding; }
}
public override void Flush()
{
m_One.Flush();
m_Two.Flush();
}
public override void Write(char value)
{
m_One.Write(value);
m_Two.Write(value);
}
}
public ConsoleCopy(string path)
{
m_OldOut = Console.Out;
try {
m_FileStream = File.Create(path);
m_FileWriter = new StreamWriter(m_FileStream)
{
AutoFlush = true
};
m_DoubleWriter = new DoubleWriter(m_FileWriter, m_OldOut);
}
catch (Exception e) {
Console.WriteLine("Cannot open file for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(m_DoubleWriter);
}
public void Dispose()
{
Console.SetOut(m_OldOut);
if (m_FileWriter != null) {
m_FileWriter.Flush();
m_FileWriter.Close();
m_FileWriter = null;
}
if (m_FileStream != null) {
m_FileStream.Close();
m_FileStream = null;
}
}
}
使用方法如下:
using (var cc = new ConsoleCopy("mylogfile.txt"))
{
Console.WriteLine("testing 1-2-3");
Console.WriteLine("testing 4-5-6");
Console.ReadKey();
}
這個方法最大的好處就是不用修改原有的Console.Write
,只要在程式入口處將主邏輯用using包住,內部所有的輸出都能同步輸出到控制檯和log檔案了。