有一個包含約 20GB、4 萬個 EML 文件的目錄,需按每個子目錄 2GB 自動分割成 10 個文件夾。
$scrfile = "d:\test" # 源文件夾
$directory = 0 # 目標文件夾計數器
$maxSize = 1825361100 # 2GB 字節數 (約 2*1024^3)
while ((dir -Path $scrfile -Filter *.eml).Count -gt 0) {
$directory++
New-Item -Path "d:\$directory" -ItemType Directory -ErrorAction Stop
$length = 0
dir -Path $scrfile -Filter *.eml | Where-Object {
$objName = $_.Name
$_.MoveTo("d:\$directory\$objName")
$length += $_.Length
if ($length -gt $maxSize) { return } # 跳出管道
}
}
Where-Object 在管道中逐個處理文件,避免一次性載入所有文件對象到內存。MoveTo 直接將文件移動到新目錄,源目錄文件數遞減,while 條件自然結束。$length 累加文件大小,超過閾值時 return 中斷當前管道,外層循環創建下一個目錄。foreach,它會將所有對象先收集到內存再迭代,極其緩慢且佔用大量內存。MoveTo 在同分區是元數據操作(極快),跨分區則為複製+刪除。-WhatIf 參數預演,確認無誤後再執行。