using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; namespace VRPlatform { public class Downloader { private readonly HttpClient _client; public Downloader() { _client = new HttpClient(); } public async Task DownloadFileAsync(string url, string destinationPath, Action progress = null) { // 获取文件大小 var fileSize = await GetFileSizeAsync(url); using (var response = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); using (var fileStream = new FileStream(destinationPath, FileMode.Append, FileAccess.Write, FileShare.None)) { var currentSize = fileStream.Length; _client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(currentSize, null); using (var responseStream = await response.Content.ReadAsStreamAsync()) { var totalRead = currentSize; var buffer = new byte[8192]; var bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length); while (bytesRead > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); totalRead += bytesRead; if (fileSize.HasValue) { var progressPercentage = (double)totalRead / fileSize.Value; progress?.Invoke(progressPercentage); } bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length); } } } } } private async Task GetFileSizeAsync(string url) { using (var response = await _client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url))) { if (response.IsSuccessStatusCode) { return response.Content.Headers.ContentLength; } else { return null; } } } } }