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();
}
相关推荐
Aimeast6 小时前
关于选择最佳.NET Core SSH服务器库的全面分析
c#·ssh
蒋劲豪7 小时前
WPF项目暴露WebApi接口;WinForm项目暴露WebApi接口;C#项目暴露WebApi接口;
开发语言·c#·wpf
code bean8 小时前
【C# 数据结构】队列 FIFO
开发语言·数据结构·c#
时光追逐者10 小时前
推荐几款开源免费的 .NET MAUI 组件库
microsoft·开源·c#·.net·.net core·maui
软件黑马王子12 小时前
C#初级教程(1)——C# 与.NET 框架:探索微软平台编程的强大组合
开发语言·c#
shepherd枸杞泡茶12 小时前
第3章 3.2 配置系统 .NET Core配置系统
后端·c#·asp.net·.net
编程乐趣14 小时前
一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略来了!
开发语言·c#
我是苏苏14 小时前
C#基础:使用Linq进行简单去重处理(DinstinctBy/反射)
开发语言·c#·linq
小小码农(找工作版)14 小时前
C#前端开发面试题
开发语言·c#
局外人_Jia16 小时前
C# 十六进制字符串转换为十进制
服务器·开发语言·c#