200MB+ CSV转JSON的PowerShell脚本性能优化咨询
大体积CSV转JSON的PowerShell脚本优化方案
针对你处理200MB以上CSV时出现的挂起/无法完成问题,核心原因是原脚本一次性将全量数据加载到内存,且管道处理、文件IO的效率低下。以下是具体优化方向和调整方案:
1. 分批处理CSV,降低内存占用
避免一次性加载整个CSV文件到内存,改用分批读取+处理的方式,控制单批数据的内存占用。
优化代码示例
$csvPath = "F:\csvs\stack.csv" $jsonPath = "F:\csvs\stack.json" $batchSize = 1000 # 可根据机器内存调整,建议1000-5000 $header = Get-Content $csvPath -First 1 $lines = Get-Content $csvPath -Skip 1 -ReadCount $batchSize # 初始化JSON文件,写入数组开头 $writer = [System.IO.StreamWriter]::new($jsonPath, $false, [System.Text.Encoding]::ASCII) $writer.Write("[") $isFirstBatch = $true foreach ($batch in $lines) { $jsonSegments = $batch | ForEach-Object { # 拼接单条数据为完整CSV行,解析为对象 $csvLine = "$header`n$_" $csvObj = ConvertFrom-Csv $csvLine -Delimiter "," -Encoding UTF8 # 明确分隔符,替代-UseCulture减少开销 # 直接构造自定义对象,替代Select-Object提升效率 $customObj = [PSCustomObject]@{ Name = $csvObj."Name" Mobile = $csvObj."Mobile" DOB = $csvObj."DOB" Email = $csvObj."Email" Father_Name = $csvObj."Father Name" Other_mobile_no = if ($csvObj."Other mobile no." -match '^\d+$') { [long]$csvObj."Other mobile no." } else { $null } Pincode = $csvObj."Pincode" State = $csvObj."State" } # 单条对象转JSON ConvertTo-Json -InputObject $customObj -Compress -Depth 100 } # 处理批次间的逗号分隔 if (-not $isFirstBatch) { $writer.Write(",") } $writer.Write($jsonSegments -join ",") $isFirstBatch = $false } # 写入JSON数组结尾,关闭流 $writer.Write("]") $writer.Close() $writer.Dispose()
2. 关键优化细节说明
- 替换
Select-Object为直接构造对象:Select-Object在处理大量数据时会产生额外的管道开销,手动构造PSCustomObject可以减少中间对象的生成,提升处理速度。 - 使用
StreamWriter替代Add-Content:Add-Content每次写入都会打开/关闭文件,频繁IO操作效率极低;StreamWriter保持文件打开状态,批量写入能大幅提升IO性能。 - 明确CSV分隔符:如果你的CSV使用固定分隔符(如逗号),直接指定
-Delimiter ","替代-UseCulture,避免系统区域设置的额外解析开销。 - 容错处理数字转换:对
Other mobile no.字段增加正则校验,避免非数字内容转换[long]时抛出错误。
3. 额外调优建议
- 调整
$batchSize:根据机器内存大小测试最优值,内存充足可适当增大(如5000),内存紧张则减小(如500)。 - 关闭不必要的PowerShell特性:处理大文件时,暂时关闭
$ErrorActionPreference = "SilentlyContinue"(需确保数据质量可靠),减少错误捕获的开销。
内容的提问来源于stack exchange,提问作者sridharnetha
相关产品推荐
相关产品推荐

