当有大量文件时,Powershell 在 "get-childitem . -directory -recurse"中运行缓慢

标签 powershell

我跑:

PS F:\> gci F:\logs\PRV_RequestLogs\inbound -r -directory | %{ $_.fullname }

它显示:

F:\logs\PRV_RequestLogs\inbound\2020-02-03
F:\logs\PRV_RequestLogs\inbound\2020-02-04
...
F:\logs\PRV_RequestLogs\inbound\2022-05-09
F:\logs\PRV_RequestLogs\inbound\2022-05-10

然后它“挂”在那里。

然后我在另一个窗口中运行以下命令,试图找出发生了什么:

PS F:\> C:\temp\handle64.exe -p 3204

我发现:

  ACC: File  (RWD)   F:\logs\PRV_RequestLogs\inbound\2020-04-28
  ...
  F08: File  (RWD)   F:\logs\PRV_RequestLogs\inbound\2020-04-28

而且目录不断变化,所以它遍历每个目录寻找子目录,里面没有但有很多文件。

完成该过程需要几个小时。没想到这个过程会这么慢。看起来它会遍历每个文件并测试它是否是一个目录。有没有更快的方法来做到这一点?我在 Windows 2012R2 上使用 powershell 5.0。

最佳答案

Get-ChildItem众所周知,递归遍历目录的速度很慢,但它是 PowerShell 内置的,它是一个非常方便且易于使用的 cmdlet。如果您追求速度和效率,您可能需要默认使用 .NET API 调用 IO.Directory .

还没有对此进行足够的测试,但我相信它应该可以工作,例如,在本例中找到任何空的且超过 90 天的目录

值得注意的是,如果运行 Windows PowerShell,此代码需要 .NET Framework 4+

$queue = [Collections.Generic.Queue[IO.DirectoryInfo]]::new()
$olderThan = [datetime]::Now.AddDays(-90)         # => Set limit date here!
$queue.Enqueue('F:\logs\PRV_RequestLogs\inbound') # => Starting path here!

while($queue.Count) {
    $dir = $queue.Dequeue()
    try {
        $isEmpty = $true
        foreach ($i in $dir.EnumerateDirectories()) {
            if($i.Attributes -band [IO.FileAttributes]::ReparsePoint) {
                # skip if it is ReparsePoint
                continue
            }
            $isEmpty = $false
            $queue.Enqueue($i)
        }

        if($isEmpty -and $dir.CreationTime -lt $olderThan -and -not $dir.EnumerateFiles().GetEnumerator().MoveNext()) {
            # output the directory if the 3 conditions are `$true`, no folders or files and older than
            $dir
        }
    }
    catch {
        # if we were unable to enumerate this directory, go next
        continue
    }
}

相关文档

关于当有大量文件时,Powershell 在 "get-childitem . -directory -recurse"中运行缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72193074/

相关文章:

windows - 在 .gitconfig 中指定 Windows 路径的语法是什么?

linux - 通过Linux的powershell使用私钥自动进行ssh登录?

arrays - 更改数组列名称

windows - 如何从 powershell 脚本中的 cmdlet 捕获退出代码

azure - 如何使用azure逻辑应用程序、函数aps从azure存储(文件共享或BLOB)中读取、写入、删除文件

asp.net - MS Exchange powershell命令创建了错误的电子邮件ID

logging - 可以修改默认 MSBUILD 记录器中使用的颜色吗?

powershell - 在数组列表中为运行空间注册 ObjectEvent

file - PowerShell Get-Content : Try{ .。 } 捕获 { ..}?

powershell - -包含或匹配多个值