PowerShell FileSystemWatcher首次触发后报错问题求助
解决FileSystemWatcher移动CSV文件时的进程占用问题
我太懂这种FileSystemWatcher的坑了!你遇到的问题核心原因很明确:Created事件触发的时机其实是文件刚开始创建的时候,这时候写入文件的进程还没释放锁,直接调用Move-Item肯定会报错。再加上你原来的代码是批量移动目录下所有CSV,这就导致了后续触发时的混乱——第二次触发时第一次的文件可能还没完全释放,第三次触发又会重复处理之前失败的旧文件。
下面给你拆解问题,再附上完整的修复代码:
问题根源拆解
- 文件锁定冲突:
Created事件触发时,文件大概率还处于被写入进程占用的状态,无法立即进行移动操作 - 批量操作逻辑缺陷:一次性移动所有CSV的写法,会导致重复处理文件,且无法精准对应触发事件的目标文件
- 无错误重试机制:遇到文件占用直接失败,后续事件触发时又会重复触发旧问题
针对性修复方案
1. 只处理触发事件的单个文件
利用事件参数里的$Event.SourceEventArgs获取刚创建的文件路径,只操作这个目标文件,避免批量操作带来的冲突。
2. 添加文件可用性检查+重试机制
通过尝试以独占模式打开文件,判断它是否已经写入完成、可以安全操作;如果被占用,就等待一段时间再重试,直到成功或达到最大重试次数。
3. 提前过滤CSV文件
给Watcher设置Filter属性,只监控.csv后缀的文件,减少无效的事件触发。
修正后的PowerShell代码
$watcher = New-Object System.IO.FileSystemWatcher $watcher.Path = "E:\CreditAdj\cashpost" $watcher.IncludeSubdirectories = $false $watcher.Filter = "*.csv" # 只监控CSV文件,减少无效触发 $watcher.EnableRaisingEvents = $true $Action = { $filePath = $Event.SourceEventArgs.FullPath $targetPath = "\\server.company.com\cashpost" $maxRetries = 5 # 最大重试次数,可根据需求调整 $retryDelay = 2000 # 每次重试间隔2秒,可根据需求调整 for ($i=1; $i -le $maxRetries; $i++) { try { # 尝试以独占模式打开文件,验证是否可操作 $fileStream = [System.IO.File]::Open( $filePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None ) $fileStream.Close() $fileStream.Dispose() # 文件可用,执行移动 Move-Item -Path $filePath -Destination $targetPath -Force Write-Host "✅ 成功移动文件: $filePath" break } catch [System.IO.IOException] { Write-Host "⚠️ 第$i次尝试移动失败,文件被占用,等待重试..." Start-Sleep -Milliseconds $retryDelay } catch { Write-Host "❌ 移动文件时出现未知错误: $_" break } } if ($i -gt $maxRetries) { Write-Host "❌ 重试$maxRetries次后仍无法移动文件: $filePath" } } # 先注销已存在的同名事件订阅,避免重复注册 if (Get-EventSubscriber -SourceIdentifier CashpostCreated -ErrorAction SilentlyContinue) { Unregister-Event -SourceIdentifier CashpostCreated } $we1 = Register-ObjectEvent $watcher Created -SourceIdentifier CashpostCreated -Action $Action
额外提示
- 如果你需要监控文件写入完成的状态,也可以考虑监听
Changed事件,但配合重试机制的Created事件已经足够解决大部分场景 - 重试次数和间隔可以根据你的业务场景调整,比如写入大文件时可以延长等待时间
内容的提问来源于stack exchange,提问作者Steven Brown
相关产品推荐
相关产品推荐

