基于CSOM的SharePoint Online大文件分块下载与进度反馈方案咨询
核心实现思路
你之前用$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
相关产品推荐
相关产品推荐

