热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用PowershellPipeline避免大型物体?

如何解决《如何使用PowershellPipeline避免大型物体?》经验,为你挑选了1个好方法。

我正在使用自定义函数基本上在8TB驱动器(数千个文件)上执行DIR命令(递归文件列表).

我的第一次迭代是:

$results = $PATHS | % {Get-FolderItem -Path "$($_)" } | Select Name,DirectoryName,Length,LastWriteTime 
$results | Export-CVS -Path $csvfile -Force -Encoding UTF8 -NoTypeInformation -Delimiter "|"

这导致了一个巨大的$ results变量,并通过强制PowerShell进程将系统降低到爬行速度,以便在处理过程中使用99%-100%的CPU.

我决定使用管道的功能直接写入CSV文件(可能释放内存),而不是保存到中间变量,并提出了这个:

$PATHS | % {Get-FolderItem -Path "$($_)" } | Select Name,DirectoryName,Length,LastWriteTime | ConvertTo-CSV -NoTypeInformation -Delimiter "|" | Out-File -FilePath $csvfile -Force -Encoding UTF8

这似乎工作正常(CSV文件正在增长......并且CPU似乎稳定)但是当CSV文件大小达到~200MB时突然停止,并且控制台的错误是" 管道已经停止 ".

我不确定CSV文件大小与错误消息有什么关系,但我无法使用任何一种方法处理这个大型目录!有关如何允许此过程成功完成的任何建议?



1> wOxxOm..:

Get-FolderItem运行robocopy以列出文件并将其输出转换为PSObject数组.这是一个缓慢的操作,严格来说,这对于实际任务不是必需的.与foreach 语句相比,流水线操作也增加了很大的开销.在数千或数十万次重复的情况下变得明显.

我们可以将流程加速到任何流水线之外,标准PowerShell cmdlet可以在10秒内在SSD驱动器上写入400,000个文件的信息.

    .NET Framework 4或更新版本(自Win8以来,可在Win7/XP上安装)IO.DirectoryInfo的EnumerateFileSystemInfos,以非阻塞管道方式枚举文件;

    PowerShell 3或更新,因为它比PS2整体更快;

    foreach 不需要为每个项创建ScriptBlock上下文的语句,因此它比ForEachcmdlet 快得多

    IO.StreamWriter 立即以非阻塞管道方式写入每个文件的信息;

    \\?\前缀技巧解除260个字符的路径长度限制;

    手动排队目录进行处理以获取"访问被拒绝"错误,否则会阻止天真的IO.DirectoryInfo枚举;

    进度报告.

function List-PathsInCsv([string[]]$PATHS, [string]$destination) {
    $prefix = '\\?\' #' UNC prefix lifts 260 character path length restriction
    $writer = [IO.StreamWriter]::new($destination, $false, [Text.Encoding]::UTF8, 1MB)
    $writer.WriteLine('Name|Directory|Length|LastWriteTime')
    $queue = [Collections.Generic.Queue[string]]($PATHS -replace '^', $prefix)
    $numFiles = 0

    while ($queue.Count) {
        $dirInfo = [IO.DirectoryInfo]$queue.Dequeue()
        try {
            $dirEnumerator = $dirInfo.EnumerateFileSystemInfos()
        } catch {
            Write-Warning ("$_".replace($prefix, '') -replace '^.+?: "(.+?)"$', '$1')
            continue
        }
        $dirName = $dirInfo.FullName.replace($prefix, '')

        foreach ($entry in $dirEnumerator) {
            if ($entry -is [IO.FileInfo]) {
                $writer.WriteLine([string]::Join('|', @(
                    $entry.Name
                    $dirName
                    $entry.Length
                    $entry.LastWriteTime
                )))
            } else {
                $queue.Enqueue($entry.FullName)
            }
            if (++$numFiles % 1000 -eq 0) {
                Write-Progress -activity Digging -status "$numFiles files, $dirName"
            }
        }
    }
    $writer.Close()
    Write-Progress -activity Digging -Completed
}

用法:

List-PathsInCsv 'c:\windows', 'd:\foo\bar' 'r:\output.csv'


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • AFNetwork框架(零)使用NSURLSession进行网络请求
    本文介绍了AFNetwork框架中使用NSURLSession进行网络请求的方法,包括NSURLSession的配置、请求的创建和执行等步骤。同时还介绍了NSURLSessionDelegate和NSURLSessionConfiguration的相关内容。通过本文可以了解到AFNetwork框架中使用NSURLSession进行网络请求的基本流程和注意事项。 ... [详细]
  • 本文介绍了SPOJ2829题目的解法及优化方法。题目要求找出满足一定条件的数列,并对结果取模。文章详细解释了解题思路和算法实现,并提出了使用FMT优化的方法。最后,对于第三个限制条件,作者给出了处理方法。文章最后给出了代码实现。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 在加载一个第三方厂商的dll文件时,提示“找不到指定模块,加载失败”。由于缺乏必要的技术支持,百思不得期间。后来发现一个有用的工具 ... [详细]
author-avatar
被爱的小花花_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有