C# 手动写入日志,过大写入新文件

老项目没有用logf4j等日志框架,使用的是手动写入文件的方式存储日志。当日志过大会出现写入缓慢问题。下面采用IO异步写入以及文件过大分片等方式解决问题。

cs 复制代码
private static readonly object _lock = new object();
private const long MaxFileSize = 10 * 1024 * 1024; // 10MB

public void SaveTextAsync(string data, string ex, string methods)
{
    try
    {
        DateTime date = DateTime.Now;
        string logData = date.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n" + data + "\r\n" + ex;
        string strDate = date.ToString("yyyyMMdd");
        string strDateTxt = strDate + ".txt";

        string programPath = AppDomain.CurrentDomain.BaseDirectory.Substring(0, 2);
        string logDir = Path.Combine(programPath + "", "\\MESBUG", strDate, methods);
        lock (_lock)
        {

            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }

            // 获取当前最新的日志文件
            string filePath = GetLatestLogFile(logDir, strDate);

            // 检查文件大小并切割
            filePath = CheckFileSizeAndRotate(filePath, logDir, strDate);

            byte[] logDataBytes = System.Text.Encoding.UTF8.GetBytes(logData + Environment.NewLine);

            FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, 4096, true);

            // 异步写入
            fs.BeginWrite(logDataBytes, 0, logDataBytes.Length, new AsyncCallback(EndWriteCallback), fs);

        }
    }
    catch (Exception ex2)
    {
        return;
    }

}

// 获取日志目录中最新的日志文件
private string GetLatestLogFile(string logDir, string strDate)
{
    // 获取日志目录下所有日志文件,按文件名排序
    var logFiles = Directory.GetFiles(logDir, $"{strDate}_*.txt")
                            .OrderByDescending(f => f)
                            .FirstOrDefault();

    if (logFiles == null)
    {
        // 如果没有找到分片日志文件,则返回默认的日志文件路径
        return Path.Combine(logDir, strDate + ".txt");
    }

    return logFiles;
}

// 检查文件大小并切割日志文件
private string CheckFileSizeAndRotate(string filePath, string logDir, string strDate)
{
    FileInfo fileInfo = new FileInfo(filePath);

    // 如果文件超过指定大小,则创建新文件
    if (fileInfo.Exists && fileInfo.Length > MaxFileSize)
    {
        string newFileName = $"{strDate}_{DateTime.Now.ToString("HHmmss")}.txt";
        return Path.Combine(logDir, newFileName);
    }

    return filePath;
}

private void EndWriteCallback(IAsyncResult ar)
{
    FileStream fs = (FileStream)ar.AsyncState;
    fs.EndWrite(ar);
    fs.Close();
}
相关推荐
★YUI★12 小时前
学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
java·学习·游戏·unity·c#
谷宇.12 小时前
【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
游戏·unity·c#·游戏程序·unity3d·游戏开发·游戏编程
LZQqqqqo13 小时前
C# 中 ArrayList动态数组、List<T>列表与 Dictionary<T Key, T Value>字典的深度对比
windows·c#·list
Dm_dotnet15 小时前
Stylet启动机制详解:从Bootstrap到View显示
c#
三千道应用题17 小时前
WPF&C#超市管理系统(6)订单详情、顾客注册、商品销售排行查询和库存提示、LiveChat报表
开发语言·c#·wpf
唐青枫21 小时前
别滥用 Task.Run:C# 异步并发实操指南
c#·.net
我好喜欢你~1 天前
C#---StopWatch类
开发语言·c#
一阵没来由的风1 天前
拒绝造轮子(C#篇)ZLG CAN卡驱动封装应用
c#·can·封装·zlg·基础封装·轮子
一枚小小程序员哈2 天前
基于微信小程序的家教服务平台的设计与实现/基于asp.net/c#的家教服务平台/基于asp.net/c#的家教管理系统
后端·c#·asp.net
Eternity_GQM2 天前
【Word VBA Zotero 引用宏错误分析与改正指南】【解决[21–23]参考文献格式插入超链接问题】
开发语言·c#·word