PowerShell用Get-ChildItem统计文件数报ObjectNotFound错误如何处理?
解决方案
错误原因
Get-ChildItem的执行分为两步:第一步拉取目录下的所有文件条目列表,第二步逐个校验条目是否匹配你指定的筛选规则(-File、*.xml后缀匹配等)。如果两步之间目标文件被其他进程移动/删除,第二步校验时就会抛出ObjectNotFound错误,这就是你遇到的偶发报错的根源。
修复方案
方案1:添加精准错误捕获(改动最小)
只忽略枚举过程中文件不存在的特定错误,不会吞掉路径无效、权限不足等其他严重错误,代码示例如下:
把你原代码中while判断部分替换为:
# 统计xml文件数,自动重试解决文件变动报错 function Get-SafeXmlCount { while($true) { try { return (Get-ChildItem -Force -File -Name (Join-Path $Myfolder "*.xml") -ErrorAction Stop).Count } catch [System.Management.Automation.ItemNotFoundException] { # 捕获文件被移动/删除的报错,直接重试统计 continue } } } if ($i -eq 100) { Write-Host '100' while((Get-SafeXmlCount) -gt 200) { Write-Host 'too many, wait 30 sec' Start-Sleep -Seconds 30 } $i = 0 }
提示:用Join-Path拼接路径比手动拼接字符串更稳妥,不会出现多斜杠、少斜杠的问题,原来的Start-Sleep -Milliseconds 30000可以直接简化为Start-Sleep -Seconds 30可读性更高。
方案2:调用.NET接口统计(性能更优)
如果目录下文件数量较多,用.NET内置的文件枚举接口比Get-ChildItem性能高很多,同时也可以规避上述报错:
function Get-SafeXmlCount { try { return [System.IO.Directory]::EnumerateFiles($Myfolder, "*.xml", [System.IO.SearchOption]::TopDirectoryOnly).Count } catch [System.IO.IOException] { # 枚举时文件变动直接重试,也可根据需求返回大于200的值触发等待 return Get-SafeXmlCount } }
调用方式和方案1完全一致,枚举过程为原子操作,不会分两步校验,出现文件变动报错的概率更低。
内容的提问来源于stack exchange,提问作者vikjon0
相关产品推荐
相关产品推荐

