You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监控正被占用的日志文件长度变化并读取新增内容?

解决被占用日志文件的监控与新增行读取问题

ReadAllLines会以独占锁打开文件,这就是它在文件被占用时报错的原因。要解决这个问题,你需要以共享读写权限打开文件流,同时记录上次读取的位置,每次只读取新增的内容。

核心实现思路

  1. 维护一个变量记录上次读取到的文件位置,初始值为0
  2. 点击按钮时,以共享模式打开文件流,跳过已读取的部分,直接读取新增内容
  3. 将新增内容拆分为行,更新标签显示新增行数,同时可以处理每一行日志
  4. 更新读取位置为当前文件长度,供下次检查使用

代码示例(以C# WinForms为例)

首先在窗体类中定义全局变量:

private long _lastReadPosition = 0;
// 替换为你的日志文件路径
private readonly string _logFilePath = @"C:\your\log\path\app.log";

然后实现按钮点击事件:

private void btnCheckLogChanges_Click(object sender, EventArgs e)
{
    try
    {
        using (var fileStream = new FileStream(_logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (var streamReader = new StreamReader(fileStream))
        {
            // 定位到上次读取结束的位置
            fileStream.Seek(_lastReadPosition, SeekOrigin.Begin);
            
            // 读取所有新增内容
            string newContent = streamReader.ReadToEnd();
            
            if (!string.IsNullOrWhiteSpace(newContent))
            {
                // 拆分新增内容为行(自动适配系统换行符)
                string[] newLines = newContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                
                // 更新标签显示新增行数
                lblLineChange.Text = $"新增行数: {newLines.Length}";
                
                // 遍历处理每一行新增日志(按需修改逻辑)
                foreach (string line in newLines)
                {
                    // 示例:将新增行添加到列表框
                    listBoxLog.Items.Add(line);
                }
            }
            
            // 更新读取位置为当前文件总长度
            _lastReadPosition = fileStream.Length;
        }
    }
    catch (FileNotFoundException)
    {
        lblLineChange.Text = "错误:日志文件不存在";
    }
    catch (UnauthorizedAccessException)
    {
        lblLineChange.Text = "错误:无权限访问日志文件";
    }
    catch (Exception ex)
    {
        lblLineChange.Text = $"错误:{ex.Message}";
    }
}

额外优化建议

  • 如果需要自动持续监控,可以添加Timer控件,设置固定间隔(比如1000ms),在Timer.Tick事件中执行上述核心逻辑
  • 若日志文件使用非UTF-8编码,需在StreamReader构造时指定编码,例如:new StreamReader(fileStream, Encoding.GetEncoding("GB2312"))
  • 处理超大日志文件时,可以考虑分批读取,避免一次性加载过多内容到内存

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 07:27:59