Downloader.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.IO;
  3. using System.Net.Http;
  4. using System.Threading.Tasks;
  5. namespace VRPlatform
  6. {
  7. public class Downloader
  8. {
  9. private readonly HttpClient _client;
  10. public Downloader()
  11. {
  12. _client = new HttpClient();
  13. }
  14. public async Task DownloadFileAsync(string url, string destinationPath, Action<double> progress = null)
  15. {
  16. // 获取文件大小
  17. var fileSize = await GetFileSizeAsync(url);
  18. using (var response = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
  19. {
  20. response.EnsureSuccessStatusCode();
  21. using (var fileStream = new FileStream(destinationPath, FileMode.Append, FileAccess.Write, FileShare.None))
  22. {
  23. var currentSize = fileStream.Length;
  24. _client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(currentSize, null);
  25. using (var responseStream = await response.Content.ReadAsStreamAsync())
  26. {
  27. var totalRead = currentSize;
  28. var buffer = new byte[8192];
  29. var bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
  30. while (bytesRead > 0)
  31. {
  32. await fileStream.WriteAsync(buffer, 0, bytesRead);
  33. totalRead += bytesRead;
  34. if (fileSize.HasValue)
  35. {
  36. var progressPercentage = (double)totalRead / fileSize.Value;
  37. progress?.Invoke(progressPercentage);
  38. }
  39. bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
  40. }
  41. }
  42. }
  43. }
  44. }
  45. private async Task<long?> GetFileSizeAsync(string url)
  46. {
  47. using (var response = await _client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url)))
  48. {
  49. if (response.IsSuccessStatusCode)
  50. {
  51. return response.Content.Headers.ContentLength;
  52. }
  53. else
  54. {
  55. return null;
  56. }
  57. }
  58. }
  59. }
  60. }