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

解决PowerShell文件监控脚本单次触发重复输出问题

解决PowerShell FileSystemWatcher单次文件变更多次触发输出的问题

问题根源

FileSystemWatcher的Changed事件并非只触发一次——大多数文本编辑器或程序在保存文件时,会执行多个操作(比如写入临时文件、替换原文件、更新文件元数据),每一步都会触发LastWrite或FileName的变更通知,导致脚本重复处理同一个变更。

解决方案

通过添加文件变更去重逻辑,记录每个文件最近一次处理的时间戳,过滤掉短时间内的重复事件。修改后的脚本如下:

Clear-Host
$queue = [System.Collections.Queue]::Synchronized((New-Object System.Collections.Queue))
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\test"
$watcher.Filter = "*.csv"
$watcher.NotifyFilter = [System.IO.NotifyFilters]'FileName, LastWrite'
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true

# 用于记录已处理文件的最近时间戳,避免重复输出
$processedFiles = @{}
$srccontents = @()

$action = { 
    $event = $Event.SourceEventArgs
    $queue.Enqueue($event)
}

# 注册事件处理器
Register-ObjectEvent $watcher "Changed" -Action $action
 
Do    
{
    if ($queue.Count -gt 0) 
    {
        $event = $queue.Dequeue()
        $path = $event.FullPath
        $fileInfo = Get-ChildItem -Path $path
        $name = $fileInfo.Name
        $changeType = $event.ChangeType
        $currentTimeStamp = $fileInfo.LastWriteTime

        # 去重逻辑:检查该文件是否在2秒内已经处理过
        if ($processedFiles.ContainsKey($path)) {
            $timeDiff = ($currentTimeStamp - $processedFiles[$path]).TotalSeconds
            if ($timeDiff -lt 2) {
                # 跳过短时间内的重复事件
                continue
            }
        }
        # 更新该文件的最后处理时间
        $processedFiles[$path] = $currentTimeStamp

        $formattedTime = $currentTimeStamp.ToString('dd/MM/yyyy HH:mm:ss')
        Write-Host "The file '$name' was $changeType at $formattedTime - Path to file is: $path"    
        Write-Host "Contents of file: "
        $srccontents = Import-Csv -Path $path 
        $srccontents | Select-Object Servername | Format-Table  

    } 
    else 
    {
        Start-Sleep -Seconds 10
    }
    Start-Sleep -Milliseconds 500
}while ($true)

关键修改说明

  1. $processedFiles哈希表:存储每个文件路径对应的最后处理时间戳,用于判断当前事件是否是重复触发
  2. 时间差过滤:设置2秒的阈值(可根据需求调整),如果当前事件的文件写入时间和上次处理时间差小于阈值,直接跳过
  3. 更新缓存时间:每次处理有效事件后,更新对应文件的缓存时间,确保后续重复事件被过滤

期望效果

单次文件变更只会触发一次输出:

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
23     829609c8-e77...                 NotStarted    False                                 ...                     
The file 'tempcsvfile.csv' was Changed at 09/02/2023 12:31:22 - Path to file is: C:\test\tempcsvfile.csv
Contents of file: 

Servername   
----------   
server1      
server2      
server3      
serversdkjfl4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:55:15