如何通过RestAPI与PowerShell分片下载BigIP F5的UCS备份文件
解决BigIP F5 UCS文件分片下载的PowerShell实现问题
先明确核心问题的解决方案,再修正代码中的错误并给出完整实现:
1. FileStream.Write方法的参数说明
$file.Write()的三个参数定义如下:
- 第一个:要写入的字节数组(对应你的
$data变量) - 第二个:数组中开始写入的起始偏移量,因为
$data是当前分片的完整字节集,直接填0即可 - 第三个:要写入的字节数,直接使用
$data.Length获取当前分片的字节长度
所以正确写法是:
$file.Write($data, 0, $data.Length)
2. 代码中的关键错误修正
- 禁止循环内关闭文件:你当前在每次循环里调用
$file.Close(),会导致第二次循环时文件流已关闭,无法继续写入,必须将关闭操作移到循环结束后。 - 转换文件长度为整数:从
Content-Range头获取的$fileLength是字符串,需转为int64类型,否则数值计算会出错。 - 修正请求头:请求分片时应使用
Range请求头(告知服务器需要的字节范围),而非Content-Range(这是响应头,用于服务器返回内容范围)。
3. 修正后的完整代码
# 提前定义必要变量:token、server、分片大小(示例为10MB) $token = "你的F5认证令牌" $server = "F5设备IP或域名" $partSizeBytes = 10485760 # 获取第一块分片并提取文件总长度 $result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/RomanTest.UCS" -Method Get -Headers $headers -SkipCertificateCheck $fileLength = [int64]($result.Headers."Content-Range" -split "/")[-1] # 初始化文件流与循环变量 $index = 0 $start = 0 $end = 0 $maxloops = [Math]::Ceiling($fileLength / $partSizeBytes) $fileName = "C:\Temp\Roman\RomanTest$(Get-Date -Format yyMMdd_HHmmss).ucs" $file = [System.IO.FileStream]::new($fileName, [System.IO.FileMode]::Create) try { # 先写入第一块分片内容 [byte[]]$firstChunk = $result.Content $file.Write($firstChunk, 0, $firstChunk.Length) $index++ while ($fileLength -gt ($end + 1)) { $start = $index * $partSizeBytes # 计算当前分片的结束位置 $end = if (($start + $partSizeBytes - 1) -lt $fileLength) { $start + $partSizeBytes - 1 } else { $fileLength - 1 } # 构造分片请求头 $headers = @{ "Content-Type" = "application/json" "X-F5-Auth-Token" = $token 'Range' = "bytes=$start-$end" } Write-Host "请求字节范围: $start-$end/$fileLength | 分片索引: $($index.ToString("000"))" $result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/RomanTest.UCS" -Method Get -Headers $headers -SkipCertificateCheck [byte[]]$data = $result.Content Write-Host "本次写入字节数: $($data.Length)" $file.Write($data, 0, $data.Length) $index++ Write-Host "完成进度: $([Math]::Ceiling($index/$maxloops*100)) %" } } finally { # 确保文件流最终被正确关闭和释放 $file.Close() $file.Dispose() }
额外提示
- 如果F5设备使用自签名证书,需添加
-SkipCertificateCheck参数绕过SSL验证。 - 使用
try/finally块可以保证无论脚本是否出错,文件流都会被正确释放,避免文件占用。
内容的提问来源于stack exchange,提问作者Roman Melekh
相关产品推荐
相关产品推荐

