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

PowerShell中递归获取指定扩展名文件路径的高效方法选型及优化问询

PowerShell中递归获取指定扩展名文件路径的高效方法选型及优化问询

我现在正琢磨着找个最高效的方式,从指定文件夹递归获取文件路径,把这些路径填充到字符串数组里。我的需求很明确:只需要文件路径就行,如果能在发现文件的同时就对它们做些处理,那就是额外的惊喜了。我目前用的是Windows 10系统上的PowerShell 7.3.6,要处理的目录里有超多子文件夹,还有各种类型的文件,我只需要筛选出指定几种扩展名的文件。

我之前试过几种方法,现在想请教大家:有没有办法优化这些方法的性能,或者还有其他更高效的实现方式?下面是我试过的几种方案和测试情况:


方案一:Get-ChildItem结合-Include参数

因为Get-ChildItem的-Filter参数不支持多条件筛选,所以我用了-Include参数来实现多扩展名过滤,代码如下:

[string]$SourcePath = "H:\Duplicate File Work\"
[string[]]$IncludeFilter = $null
[string[]]$FilePathCollection = $null

$IncludeFilter += "*.doc"
$IncludeFilter += "*.xls"
$IncludeFilter += "*.ppt"

$StopWatch = [System.Diagnostics.Stopwatch]::New()
$StopWatch.Start()

$FilePathCollection = Get-ChildItem -Path $SourcePath -Include $IncludeFilter -Recurse

Write-Host $FilePathCollection.Count
$StopWatch.Stop()
$StopWatch.Elapsed

测试结果:找到了22853个文件,耗时大约4分27秒。但这个方法的问题是,必须等Get-ChildItem把所有文件路径都收集完、填充到数组里之后,才能对文件进行处理,没办法做到边发现边处理。


方案二:使用.NET的[IO.Directory]::GetFiles()

我还试了用.NET类库的GetFiles方法,代码如下:

[string]$SourcePath = "H:\Duplicate File Work\"
[string[]]$IncludeFilter = $null
[string[]]$FilePathCollection = $null

$IncludeFilter += "*.doc"
$IncludeFilter += "*.xls"
$IncludeFilter += "*.ppt"

$StopWatch = [System.Diagnostics.Stopwatch]::New()
$StopWatch.Start()

foreach ($Filter in $IncludeFilter) {
    foreach ($File in [IO.Directory]::GetFiles($SourcePath, $Filter, "AllDirectories")) {
        $FileAttributes = (Get-ItemProperty -Path $File).Attributes -split ", "
        if ($FileAttributes -match "Hidden") {
            Continue
        }
        else {
            $FilePathCollection += $File
        }
    }
}

Write-Host $FilePathCollection.Count
$StopWatch.Stop()
$StopWatch.Elapsed

测试结果:同样找到了22853个文件,但耗时约6分6秒。不过这个方法的优点是,能在发现文件的同时就进行处理——比如我在代码里加了一段逻辑,用来过滤掉隐藏文件。

另外我还试了EnumerateFiles和EnumerateFileSystemEntries方法,它们找到的文件数量和GetFiles一样,但耗时更长,分别是6分49秒和6分42秒。

这里要提一下:Get-ChildItem默认不会搜索隐藏文件,而这几个.NET方法会,所以我特意加了隐藏文件的过滤逻辑,保证两种方法的结果一致。


验证结果一致性

为了确认Get-ChildItem和GetFiles找到的是完全相同的文件,我写了一段对比代码:

[string]$SourcePath = "H:\Duplicate File Work\"
[string[]]$IncludeFilter = $null
[string[]]$FilePathCollection1 = $null
[string[]]$FilePathCollection2 = $null
[system.object]$CompareObjects = $null
[system.object]$StopWatch = [System.Diagnostics.Stopwatch]::New()

$IncludeFilter += "*.doc"
$IncludeFilter += "*.xls"
$IncludeFilter += "*.ppt"

$StopWatch.Start()
foreach ($Filter in $IncludeFilter) {
    foreach ($File in [IO.Directory]::GetFiles($SourcePath, $Filter, "AllDirectories")) {
        $FileAttributes = (Get-ItemProperty -Path $File).Attributes -split ", "
        if ($FileAttributes -match "Hidden") {
            Continue
        }
        else {
            $FilePathCollection1 += $File
        }
    }
}
Write-Host $FilePathCollection1.Count
$StopWatch.Stop()
$StopWatch.Elapsed

$StopWatch.Reset()
$StopWatch.Start()
foreach ($File in Get-ChildItem -Path $SourcePath -Include $IncludeFilter -Recurse) {
    $FilePathCollection2 += $File
}
Write-Host $FilePathCollection2.Count
$StopWatch.Stop()
$StopWatch.Elapsed

$CompareObjects = Compare-Object -ReferenceObject $FilePathCollection1 -DifferenceObject $FilePathCollection2
$CompareObjects | Out-GridView

对比结果显示,两种方法找到的文件完全一致,没有差异。


现在回到我的核心问题:有没有其他更高效的方法能实现我的需求?或者有没有办法优化现有的这些方案,让它们的执行速度更快?

备注:内容来源于stack exchange,提问作者Don

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:44:52