using System; using System.IO; using System.Text; namespace YiDa_WinForm { /// /// 日志辅助类(确保线程安全,正常写入文件,路径清晰,新增WinForm界面显示支持) /// public static class LogHelper { // 日志根目录(基于程序运行目录,确保路径统一) private static readonly string _logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log"); // 线程锁(保证多线程写入日志不冲突) private static readonly object _lockObj = new object(); /// /// 新增:日志事件(当有新日志生成时触发,供MainForm订阅更新界面) /// public static event Action OnLogGenerated; /// /// 静态构造函数(初始化日志目录) /// static LogHelper() { try { if (!Directory.Exists(_logDirectory)) { Directory.CreateDirectory(_logDirectory); } } catch (Exception ex) { // 兜底:输出到WinForm调试窗口(可在VS的“输出”面板查看) System.Diagnostics.Debug.WriteLine($"【LogHelper初始化错误】创建日志目录失败:{ex.ToString()}"); } } /// /// 写入日志(追加模式,每日一个文件,UTF-8编码,新增界面日志推送) /// /// 日志内容 public static void AppendLog(string content) { // 空内容直接返回,避免无效写入 if (string.IsNullOrWhiteSpace(content)) { return; } try { // 1. 构造当日日志文件名(基于程序运行目录,路径绝对清晰) string todayLogFileName = $"log_{DateTime.Now:yyyyMMdd}.txt"; string todayLogFileFullPath = Path.Combine(_logDirectory, todayLogFileName); // 2. 拼接详细时间戳和日志内容,格式清晰便于排查 string logContent = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {content}"; // 3. 加锁保证线程安全(防止多线程同时写入同一文件) lock (_lockObj) { // 4. 以追加模式写入,自动创建文件,指定UTF-8无BOM编码 using (StreamWriter sw = new StreamWriter( todayLogFileFullPath, append: true, encoding: new UTF8Encoding(false))) { sw.WriteLine(logContent); // 强制刷新缓冲区,确保日志立即写入文件(避免缓存积压) sw.Flush(); } // 5. 输出到VS调试窗口(保留原有功能) System.Diagnostics.Debug.WriteLine(logContent); } // 6. 新增:触发日志事件,推送日志内容到WinForm界面(不放在lock内,提高性能) OnLogGenerated?.Invoke(logContent); } catch (Exception ex) { // 兜底:输出完整异常信息到VS调试窗口(包含堆栈跟踪,便于排查) System.Diagnostics.Debug.WriteLine($"【LogHelper写入错误】写入日志失败:{ex.ToString()}"); } } } }