You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArrayList是否已过时?求支持.Remove()的替代类型及代码优化建议

关于PowerShell中ArrayList替代方案及代码优化的问题

问题描述

听说ArrayList是老旧的数据结构,不该再用,对此我有疑问。想知道有没有更优的数组类型可以在do while循环里使用.Remove()方法?

我的代码逻辑:遍历DestSSD中的每个SSD,用Test-Path检测是否可访问,不可访问就跳过;可访问则执行文件复制,然后把该SSD从列表中移除。只对首次尝试失败的SSD重复执行循环,直到达到$maxAttempts(最多3次)或所有SSD复制完成。另外,希望能得到代码和逻辑的优化建议,我还在学习中。

原代码

[System.Collections.ArrayList]$DestSSD = @(
    "B:\",
    "A:\",
    "T:\"
)
$Source="c:\source"

$maxAttempts = 3
$attempts = 0


######__MAIN__######
do {
    $attempts++
    foreach ($ssd in $($DestSSD)) {
        Write-Host "Accessing SSD: "$ssd
        if (Test-Path $ssd ) {
            #Copy File below
            robocopy $Source $ssd /COPY:DAT /R:0 /np /tee /LOG+:"C:\Documents\logs\SSD_LOG.log"
            Write-Host "Copy successful!"
            $DestSSD.Remove($ssd)
            Write-Host "Remained SSDs to check: "$DestSSD.Count
            if($DestSSD.Count -eq 0){
                "Last SSD copy finished!"
                Exit
            }
        }else {
            Write-Host "Copy failed... Trying again!"
            Start-Sleep -s 5
        }
   }
} while ($attempts -lt $maxAttempts) #3 attemps with -lt (Less Than)
Write-Host "Max attempts reached!"
Exit

一、ArrayList的替代方案

推荐使用 System.Collections.Generic.List[string],这是现代且类型安全的泛型列表,性能优于ArrayList,同样支持.Remove()方法,用法和ArrayList高度兼容:

# 声明方式
$DestSSD = [System.Collections.Generic.List[string]]@("B:\", "A:\", "T:\")

二、代码与逻辑优化建议

核心优化点

  1. 避免遍历中直接修改原列表:原代码通过$($DestSSD)创建副本,但直接调用.Remove()仍可能引发意外逻辑问题,建议维护独立的待重试列表。
  2. 精准处理重试逻辑:仅对每次尝试失败的SSD进行重试,避免重复处理已成功的目标。
  3. 完善错误判断:robocopy的退出码0/1均表示成功,需针对性判断复制结果,而非仅依赖路径检测。
  4. 避免强制终止脚本:用break替代Exit,更优雅地控制流程。

优化后代码

# 使用泛型List替代ArrayList
$DestSSD = [System.Collections.Generic.List[string]]@("B:\", "A:\", "T:\")
$Source = "c:\source"
$maxAttempts = 3
$logPath = "C:\Documents\logs\SSD_LOG.log"

# 确保日志目录存在
$logDir = Split-Path -Path $logPath -Parent
if (-not (Test-Path -Path $logDir)) {
    New-Item -Path $logDir -ItemType Directory | Out-Null
}

# 初始化待重试列表
$retrySSDs = $DestSSD.Clone()

for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
    Write-Host "=== 第 $attempt 次尝试 ==="
    # 临时存储本次尝试失败的SSD
    $failedSSDs = [System.Collections.Generic.List[string]]@()

    foreach ($ssd in $retrySSDs) {
        Write-Host "正在访问SSD: $ssd"
        # 明确检测目标是否为可访问的目录
        if (Test-Path -Path $ssd -PathType Container) {
            # 执行文件复制
            robocopy $Source $ssd /COPY:DAT /R:0 /np /tee /LOG+:$logPath
            
            # 检查robocopy退出码:0=无文件需复制,1=复制成功,均视为成功
            if ($LASTEXITCODE -le 1) {
                Write-Host "复制成功!已移除SSD: $ssd"
                $DestSSD.Remove($ssd)
            } else {
                Write-Host "复制失败(退出码: $LASTEXITCODE),将重试SSD: $ssd"
                $failedSSDs.Add($ssd)
                Start-Sleep -Seconds 5
            }
        } else {
            Write-Host "SSD不可访问,将重试SSD: $ssd"
            $failedSSDs.Add($ssd)
            Start-Sleep -Seconds 5
        }
    }

    # 更新待重试列表为本次失败的SSD
    $retrySSDs = $failedSSDs

    # 无待重试目标则提前结束循环
    if ($retrySSDs.Count -eq 0) {
        Write-Host "所有SSD复制完成!"
        break
    }

    Write-Host "第 $attempt 次尝试结束,剩余待重试SSD数量: $($retrySSDs.Count)`n"
}

# 输出最终结果
if ($retrySSDs.Count -gt 0) {
    Write-Host "已达到最大尝试次数 ($maxAttempts),以下SSD复制失败: $($retrySSDs -join ', ')"
}

内容的提问来源于stack exchange,提问作者Filip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:42:41