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

PowerShell脚本分片上传Dalux API时出现内容大小匹配错误

PowerShell文件分片上传API报错修复方案

问题背景

已有可正常运行的Python分片上传脚本,但转换为PowerShell后,API返回400错误:

{
"httpStatusCode": 400,
"errorCode": "E40004",
"errorCodeMessage": "HeaderValidationFailed",
"message": "Content-Range header size 300000 is not the same as the content size 901216",
"logTime": "2024-02-08T16:02:46.3439873Z"
}

错误原因

原PowerShell脚本中[System.IO.File]::ReadAllBytes($file)[$rangeStart..$rangeEnd]的分片读取方式存在问题:

  • $rangeStart..$rangeEnd生成包含300000个元素的整数数组,用它索引字节数组时,若文件总字节数小于$rangeEnd,PowerShell会返回从$rangeStart到文件末尾的所有字节,再补充大量$null值,最终数组长度远大于预期,导致实际传输内容与Content-Range声明不符。
  • 该方式一次性读取整个文件到内存,效率极低且占用过多资源。

修复后的PowerShell脚本

$filePath = "\Downloads\bim\7_LARD_90_99.ifc"
$rangeStart = 0
$rangeEnd = 299999
# 自动获取文件总大小,替代硬编码
$totalFileSize = (Get-Item $filePath).Length

$headers = @{
    "X-API-KEY" = "xxx-xxx-xxx"
    "Content-Disposition" = "form-data; filename=7_LARD_90_99.ifc"
    "Content-Type" = "application/octet-stream"
    "Content-Range" = "bytes $rangeStart-$rangeEnd/$totalFileSize"
}

try {
    $bytesToRead = $rangeEnd - $rangeStart + 1
    $fileChunkBytes = New-Object byte[] $bytesToRead

    # 使用文件流精准读取指定范围的字节
    using ($fileStream = [System.IO.File]::OpenRead($filePath)) {
        # 定位到分片起始位置
        $fileStream.Seek($rangeStart, [System.IO.SeekOrigin]::Begin) | Out-Null
        # 读取指定长度的字节
        $actualBytesRead = $fileStream.Read($fileChunkBytes, 0, $bytesToRead)
        
        # 处理文件末尾的分片(实际读取字节数小于预期)
        if ($actualBytesRead -lt $bytesToRead) {
            $fileChunkBytes = $fileChunkBytes[0..($actualBytesRead - 1)]
            # 更新Content-Range头,匹配实际传输的分片范围
            $headers["Content-Range"] = "bytes $rangeStart-$($rangeStart + $actualBytesRead - 1)/$totalFileSize"
        }
    }

    Write-Host "实际读取分片大小: $($fileChunkBytes.Length) 字节"

    # 用Invoke-WebRequest获取完整响应信息(含状态码)
    $response = Invoke-WebRequest -Method Post `
        -Uri "https://field.dalux.com/service/api/1.0/projects/xxxxxxx/file_areas/yyyyyyy/upload/zzzzzzzzz" `
        -Headers $headers `
        -ContentType "application/octet-stream" `
        -Body $fileChunkBytes `
        -UseBasicParsing

    Write-Host "响应状态码: $($response.StatusCode)"
    Write-Host "响应内容:"
    $response.Content | ConvertFrom-Json
} catch {
    Write-Host "发生错误: $_"
    # 输出API返回的详细错误信息
    if ($_.Exception.Response) {
        $errorStream = $_.Exception.Response.GetResponseStream()
        $reader = New-Object System.IO.StreamReader($errorStream)
        $errorContent = $reader.ReadToEnd()
        Write-Host "API错误响应: $errorContent"
    }
}

关键修复说明

  1. 精准读取分片:使用FileStream的Seek方法定位到分片起始位置,再用Read方法读取指定长度的字节,确保传输内容大小与Content-Range声明完全一致。
  2. 动态处理末尾分片:若为文件最后一个分片,实际读取字节数可能小于预期,此时自动更新Content-Range头,匹配实际传输的范围。
  3. 优化内存使用:避免一次性读取整个文件到内存,适配大文件上传场景。
  4. 完善调试信息:改用Invoke-WebRequest获取响应状态码和原始内容,便于问题排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:35:59