C# 为日志文件使用StreamWriter的正确方法

C# 为日志文件使用StreamWriter的正确方法,c#,logging,streamwriter,C#,Logging,Streamwriter,仅供参考-原始海报不能使用开源或第三方库 我正在创建一个将使用日志文件的应用程序。 我想知道创建日志文件的“正确”方法是什么(在系统管理、良好实践、资源管理等方面) 第一种方法: public partial class Form1 : Form { string path = "SomeFile.txt"; StreamWriter writer; public Form1() { writer = new Strea

仅供参考-原始海报不能使用开源或第三方库

我正在创建一个将使用日志文件的应用程序。 我想知道创建日志文件的“正确”方法是什么(在系统管理、良好实践、资源管理等方面)

第一种方法:

    public partial class Form1 : Form
{
    string path = "SomeFile.txt";
    StreamWriter writer;
    public Form1()
    {
        writer = new StreamWriter(path);
        InitializeComponent();

    }
    public void LogWriteLine(string print)
    {
        writer.WriteLine(print);
    }
    protected override void Dispose(bool disposing)
    {
        if (writer != null) writer.Close();
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
}
第二种方法:

    public partial class Form1 : Form
{
    string path = "SomeFile.txt";
    public Form1()
    {
        InitializeComponent();

    }
    public void LogWriteLine(string print)
    {
        using (StreamWriter writer = new StreamWriter(path))
        {
            writer.WriteLine(print);
        }
    }
}
我知道,在第二种方法中,我可以在线查看日志文件,而在第一种方法中,我只能在应用程序关闭后查看日志文件,这与我的使用无关

如果可能的话,我想得到一个“一般”答案(对于经常使用LogWriteLine的应用程序和很少使用LogWriteLine的应用程序,如果这对本次讨论很重要的话)


谢谢。

既然您不能使用外部代码,我建议简单就是好的。
StreamWriter有多种挑战:

1] 如果多个线程想同时登录怎么办?
2] 关于性能,您不应该一直打开
StreamWriter
吗?(见#1)。
3] 如果要存档或删除日志,该怎么办

避免使用
StreamWriter
可以为您解决这些问题。微软已经提供了一个方便的附加api

公共类记录器
{
私有只读字符串文件;
公共记录器(字符串文件)
{
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(文件));
this.file=文件;
}
公共作废日志(字符串文本)
{
字符串行=DateTime.UtcNow.ToString(“o”)+“”+text+Environment.NewLine;
//启动后台登录,不要减慢主应用程序的速度
System.Threading.Tasks.Task.Run(异步()=>
{
//尝试10次登录两个调用同时在文件中得到的不太可能的事件
对于(int i=0;i<10;i++)
{
尝试
{
//这样可以避免在需要清理日志文件时锁定日志文件,并为每一行添加时间戳。
wait System.IO.File.AppendAllTextAsync(文件,行);
打破
}
捕获(System.IO.IOException)
{
//稍等一下,不太可能碰到这个,但以防万一。。。
等待任务。延迟(20);
}
}
}).GetAwaiter();
}
}
用法:

Logger Logger=new Logger(“c:/logs/log.txt”);//改变你的道路
logger.Log($“事件发生时数据为{data.Value}”);

当谈到性能和优化时,史蒂夫在评论中提到了第二种方法


如果从该表单打开,则第一个方法将有问题 另一个表单,并希望写入相同的日志文件 除非您希望程序的每个类都有不同的日志)

然而,如果你愿意,你应该使用第一种方法

  • 不允许用户在应用程序运行时访问日志
  • 如果目标设备的内存(RAM)没有问题,因为这种方法需要更多内存
  • 如果你想,你应该使用第二种方法

  • 为应用程序中的所有模块创建通用日志
  • 日志记录的简单性
  • 减轻RAM的负担
  • 允许任何人在应用程序运行时访问日志

  • 但是,您应该在professional或release build中使用云日志,以获得更好的性能和分析,例如Firebase或自定义日志桥

    如果从该表单打开另一个表单并希望在同一日志文件中写入,则第一种方法将出现问题(除非您希望程序的每个类都有不同的日志,否则应该如此)顺便问一下,您知道有很多日志库可以帮助您避免重新发明轮子吗?您提到的问题是可以解决的,作为一种通用的日志管理方法,我想问更多的是,“正确”的方法是什么。关于日志库,不,我不知道,我会查出来的,谢谢。@YakirShlezinger“正确”的方法是,至少你有一个外部类来做日志记录。外部类在开始时打开文件,每次写入(或每x秒)都执行
    Flush()
    ,以确保文件已写入。打开该文件时,其他程序可以使用这些选项打开该文件进行读取。
    Write
    方法使用一个
    lock
    来确保不存在多个写入操作,依此类推。甚至还有切换日志文件等问题(通常情况下,您不希望每次切换时都有1tb的日志文件)方法甚至不是这样…一个好的日志是一个分层日志,很容易搜索,其中文本和值是分开的…每个消息都有一些属性,因此可以进行搜索。一个文本文件对于一个好的日志就像一个垃圾桶对于一个库一样。有关如何使用好的日志的示例,请参阅ASP.NET核心日志记录可以做到:我不能使用任何不是来自Microsoft的框架,我们正在一个独立的高安全网络中工作。不用担心。我使用了一个简单的日志记录类进行了更新。如果需要,您可以扩展它以每天生成一个新的文件名,并旋转文件、编写为json等