解决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)
关键修改说明
$processedFiles哈希表:存储每个文件路径对应的最后处理时间戳,用于判断当前事件是否是重复触发- 时间差过滤:设置2秒的阈值(可根据需求调整),如果当前事件的文件写入时间和上次处理时间差小于阈值,直接跳过
- 更新缓存时间:每次处理有效事件后,更新对应文件的缓存时间,确保后续重复事件被过滤
期望效果
单次文件变更只会触发一次输出:
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
相关产品推荐
相关产品推荐

