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

基于CSOM的SharePoint Online大文件分块下载与进度反馈方案咨询

SharePoint Online CSOM PowerShell 大文件带进度下载解决方案

核心实现思路

你之前用$File.OpenBinaryStream()触发ExecuteQuery()时会一次性拉取全量文件流,导致进程阻塞无进度反馈。可以改用分段范围请求的方案,按固定字节分片拉取文件,实时计算下载进度。

具体实现代码

# 配置参数
$siteUrl = "https://domain.sharepoint.com/sites/collection1/site1/"
$fileServerRelativeUrl = "/sites/collection1/site1/Ordner/Datei.zip"
$localSavePath = "C:\Downloads\Datei.zip"
$chunkSize = 10MB # 可自定义分段大小,建议1-50MB根据网络调整

# 初始化CSOM上下文
$Cred = Get-Credential
$CTX = [Microsoft.SharePoint.Client.ClientContext]::new($siteUrl)
$CTX.Credentials = [Microsoft.SharePoint.Client.SharePointOnlineCredentials]::new($Cred.UserName, $Cred.Password)
$CTX.Load($CTX.Web)
$CTX.ExecuteQuery()

# 获取文件元信息
$File = $CTX.Web.GetFileByServerRelativeUrl($fileServerRelativeUrl)
$CTX.Load($File)
$CTX.ExecuteQuery()
$totalFileSize = $File.Length
$downloadedSize = 0

# 获取SharePoint身份验证Cookie
$authCookie = $CTX.Credentials.GetAuthenticationCookie($siteUrl, $true)

# 初始化HttpClient
Add-Type -AssemblyName System.Net.Http
$handler = [System.Net.Http.HttpClientHandler]::new()
$handler.CookieContainer.SetCookies([Uri]$siteUrl, $authCookie)
$httpClient = [System.Net.Http.HttpClient]::new($handler)
$fileUrl = "$siteUrl/_api/web/getfilebyserverrelativeurl('$fileServerRelativeUrl')/`$value"

# 创建本地文件流
$localFileStream = [System.IO.File]::Create($localSavePath)

# 分段下载
while ($downloadedSize -lt $totalFileSize) {
    $endByte = [Math]::Min($downloadedSize + $chunkSize - 1, $totalFileSize - 1)
    $rangeHeader = [System.Net.Http.Headers.RangeHeaderValue]::new($downloadedSize, $endByte)
    $requestMsg = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $fileUrl)
    $requestMsg.Headers.Range = $rangeHeader

    $response = $httpClient.SendAsync($requestMsg, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).Result
    $responseStream = $response.Content.ReadAsStreamAsync().Result
    $responseStream.CopyTo($localFileStream)

    $downloadedSize = $endByte + 1
    $progressPercent = [Math]::Round(($downloadedSize / $totalFileSize) * 100, 2)
    Write-Progress -Activity "正在下载文件 $($File.Name)" -Status "已下载 $($downloadedSize/1MB)MB / $($totalFileSize/1MB)MB" -PercentComplete $progressPercent
}

# 释放资源
$localFileStream.Flush()
$localFileStream.Close()
$httpClient.Dispose()
$CTX.Dispose()

Write-Host "文件下载完成,已保存至 $localSavePath"

方案说明

  • 该方案通过HTTP Range头实现分段拉取,不会触发CSOM全量流加载的阻塞问题,进度反馈实时性高
  • 分段大小$chunkSize可根据网络环境调整,网络不稳定建议调小为1-5MB,稳定场景可调整为20-50MB提升下载效率
  • 自动复用CSOM的身份凭据,不需要额外输入账号密码或者申请应用权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:06:01