如何修改基于.NET的PowerShell脚本获取大目录的文件大小与修改时间?
修改脚本以返回文件大小和修改时间
针对你的超大目录场景,以下是修改后的脚本,既能保持.NET方法的高效性,又能返回文件大小和修改时间:
版本1:内存友好型(适合百万级文件)
Invoke-Command -ComputerName (Get-Content servers.txt) -ScriptBlock { $directoryPath = 's:\some\path\structure' $outputPath = 'c:\temp\outfile.txt' Try { # 延迟枚举文件,避免一次性加载所有路径到内存 $outputLines = foreach ($filePath in [System.IO.Directory]::EnumerateFiles($directoryPath, '*.*', 'AllDirectories')) { try { $fileInfo = [System.IO.FileInfo]::new($filePath) # 拼接路径、大小(字节)、修改时间(可自定义格式) "$($fileInfo.FullName)|$($fileInfo.Length)|$($fileInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss'))" } catch { # 记录单个文件的访问错误,不中断整体流程 "ERROR: 无法访问文件 $filePath - $($_.Exception.Message)" } } # 批量写入结果到文件 [System.IO.File]::WriteAllLines($outputPath, $outputLines) } catch { # 捕获目录枚举的全局错误(如根目录无权限) [System.IO.File]::WriteAllLines($outputPath, "ERROR: 枚举目录失败 - $($_.Exception.Message)") } }
版本2:极致低内存(超大规模文件,千万级)
如果文件数量突破千万级,用StreamWriter逐行写入可以进一步降低内存占用:
Invoke-Command -ComputerName (Get-Content servers.txt) -ScriptBlock { $directoryPath = 's:\some\path\structure' $outputPath = 'c:\temp\outfile.txt' Try { # 创建流写入器,逐行写入文件 $writer = [System.IO.StreamWriter]::new($outputPath) try { foreach ($filePath in [System.IO.Directory]::EnumerateFiles($directoryPath, '*.*', 'AllDirectories')) { try { $fileInfo = [System.IO.FileInfo]::new($filePath) $line = "$($fileInfo.FullName)|$($fileInfo.Length)|$($fileInfo.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss'))" $writer.WriteLine($line) } catch { $writer.WriteLine("ERROR: 无法访问文件 $filePath - $($_.Exception.Message)") } } } finally { # 确保写入器被正确关闭 $writer.Close() $writer.Dispose() } } catch { # 捕获全局错误并写入文件 if ($writer) { $writer.WriteLine("ERROR: 枚举目录失败 - $($_.Exception.Message)") $writer.Close() $writer.Dispose() } else { [System.IO.File]::WriteAllLines($outputPath, "ERROR: 初始化写入器失败 - $($_.Exception.Message)") } } }
关键说明:
- 延迟枚举:
[System.IO.Directory]::EnumerateFiles是延迟加载的,不会一次性把所有文件路径加载到内存,这是处理百万级文件的核心优势。 - FileInfo属性:通过
[System.IO.FileInfo]类获取Length(文件大小,单位字节)和LastWriteTime(最后修改时间),比PowerShell原生命令快得多。 - 错误处理:加入了单个文件的异常捕获,避免因某一个文件访问权限问题导致整个脚本中断;全局异常捕获处理目录枚举的整体错误。
- 格式自定义:时间格式可以通过
ToString('yyyy-MM-dd HH:mm:ss')修改成你需要的样式,分隔符|可以换成逗号、制表符等,方便后续用Import-Csv解析:Import-Csv -Path 'c:\temp\outfile.txt' -Delimiter '|' -Header 'FullName', 'Size', 'LastWriteTime'
内容的提问来源于stack exchange,提问作者dbutts
相关产品推荐
相关产品推荐

