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();
}
相关推荐
狼与自由30 分钟前
clickhouse引擎
clickhouse·c#·linq
wangnaisheng44 分钟前
【C#】死锁详解:发生原因、优化解决方案
c#
tiger从容淡定是人生1 小时前
AI替代软件战略(一):从 CCleaner 到 MCP 架构重构 —— TigerCleaner 的工程实践
人工智能·重构·架构·c#·mcp
宝桥南山21 小时前
GitHub Models - 尝试一下使用GitHub Models
microsoft·ai·微软·c#·github·.netcore
hixiong1231 天前
C# OpenvinoSharp部署INSID3
开发语言·人工智能·ai·c#·openvinosharp
星辰徐哥1 天前
Unity C#入门:变量的定义与访问权限(public/private)
unity·c#·lucene
leoufung1 天前
LeetCode 30:Substring with Concatenation of All Words 题解(含 C 语言 uthash 实现)
c语言·leetcode·c#
hacker7071 天前
Visual Studio安装教程(C#开发版)
ide·c#·visual studio
SKY -dada1 天前
Understand 使用教程
开发语言·c#·流程图·软件构建·敏捷流程·代码复审·源代码管理
William_cl1 天前
【C#/.NET 进阶】ASP.NET 架构与最佳实践:DI 依赖注入(IoC 核心)从入门到避坑
c#·asp.net·.net