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

FileSystemWatcher监听日志文件变更时无事件触发,求解决方案

问题描述

我尝试用FileSystemWatcher监听日志文件的变更,触发时执行命令。在记事本中保存文件时功能正常,但实际写入日志的应用程序操作时完全无效。我看到过相关说法,这类问题可能是因为应用程序采用了“创建含新数据的日志副本→删除原文件→重命名副本”的更新方式,所以我尝试监听删除、创建和重命名事件,但依然没效果。

我使用的是FileSystemWatcher的派生类(因业务需求必须为派生类,其他功能不在本次讨论范围内):

class LogWatcher : System.IO.FileSystemWatcher {
    [System.Management.Automation.Job[]] $Event
    [string] $LogName = 'Endpointlog.txt'
    [string] $LogFolder = ('C:\Users\' + $env:USERNAME + '\AppData\Roaming\<pathtologfolder>')
    LogWatcher () : base($this.LogFolder, $this.LogName) {
        $this.Event = (new-object System.Management.Automation.Job[] 4)
        $this.EnableRaisingEvents = $true;
        $fsaction = {
            param ( 
                [System.Object] $sender,
                [System.IO.FileSystemEventArgs] $e
            )
            $sender | fl
            $e | fl
        }
        $rnaction = {
            param ( 
                [System.Object] $sender,
                [System.IO.renamedEventArgs] $e
            )
            $sender | fl
            $e | fl
        }
        $this.NotifyFilter =[System.IO.NotifyFilters]::Attributes, [System.IO.NotifyFilters]::CreationTime,     [System.IO.NotifyFilters]::DirectoryName, [System.IO.NotifyFilters]::FileName, [System.IO.NotifyFilters]::LastAccess, [System.IO.NotifyFilters]::LastWrite, [System.IO.NotifyFilters]::Security, [System.IO.NotifyFilters]::Size 
        $this.Event[0] = register-ObjectEvent -InputObject $this -EventName changed -Action $fsaction
        $this.Event[1] = register-ObjectEvent -InputObject $this -EventName created -Action $fsaction
        $this.Event[2] = register-ObjectEvent -InputObject $this -EventName deleted -Action $fsaction
        $this.Event[3] = register-ObjectEvent -InputObject $this -EventName renamed -Action $rnaction
    }
}

初始化代码:

$lw = [LogWatcher]::new();

日志文件每几秒更新一次,我预期$lw.Event中至少有一个Job处于运行状态而非“未启动”,但只有用记事本打开并保存(此时记事本提示“另存为”而非直接保存)时,才有一个Job状态变化。我还是认为问题出在文件被复制、删除并重命名的操作上,请问有没有办法捕获这类操作的事件?

解决方案
  • 监听整个日志目录:原代码绑定的是单个文件,当文件被删除重建后,监听句柄会失效。改为监听整个日志目录(构造函数中只传入目录路径,或者将Filter设为目标日志文件名),这样无论文件被删除、创建还是重命名,都能捕获到对应事件。
  • 优化事件监听逻辑:
    • 在Created事件触发时,检查新文件的名称是否为目标日志文件,确认后再执行后续操作;
    • 当Deleted事件触发且涉及目标文件时,记录该动作,后续结合Renamed或Created事件判断完整的更新流程。
  • 增大事件缓冲区:如果日志更新频繁,FileSystemWatcher的默认缓冲区可能溢出导致丢事件。可以在构造函数中添加$this.InternalBufferSize = 65536(最大值为64KB),提升缓冲区容量。
  • 重新绑定失效监听:当捕获到目标文件被删除的事件后,重新注册针对该文件的Changed事件监听,避免原监听失效后无法捕获后续变更。
  • 搭配轮询兜底:如果FileSystemWatcher仍不稳定,可添加定时轮询逻辑,定期检查日志文件的最后修改时间或大小,当检测到变化时执行命令。这种方式稳定性更高,适合对可靠性要求高的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:37:03