FileResumeRequest.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System.IO;
  2. using UnityEngine.Networking;
  3. namespace YooAsset
  4. {
  5. internal class FileResumeRequest : IWebRequester
  6. {
  7. private string _tempFilePath;
  8. private UnityWebRequest _webRequest;
  9. private DownloadHandlerFileRange _downloadHandle;
  10. private ulong _fileOriginLength = 0;
  11. public ERequestStatus Status { private set; get; } = ERequestStatus.None;
  12. public float DownloadProgress { private set; get; }
  13. public ulong DownloadedBytes { private set; get; }
  14. public string RequestNetError { private set; get; }
  15. public long RequestHttpCode { private set; get; }
  16. public FileResumeRequest() { }
  17. public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
  18. {
  19. if (Status != ERequestStatus.None)
  20. throw new System.Exception("Should never get here !");
  21. _tempFilePath = bundleInfo.TempDataFilePath;
  22. long fileBytes = bundleInfo.Bundle.FileSize;
  23. // 获取下载的起始位置
  24. long fileLength = -1;
  25. if (File.Exists(_tempFilePath))
  26. {
  27. FileInfo fileInfo = new FileInfo(_tempFilePath);
  28. fileLength = fileInfo.Length;
  29. _fileOriginLength = (ulong)fileLength;
  30. DownloadedBytes = _fileOriginLength;
  31. }
  32. // 检测下载起始位置是否有效
  33. if (fileLength >= fileBytes)
  34. {
  35. if (File.Exists(_tempFilePath))
  36. File.Delete(_tempFilePath);
  37. }
  38. // 创建下载器
  39. _webRequest = DownloadHelper.NewRequest(requestURL);
  40. #if UNITY_2019_4_OR_NEWER
  41. var handler = new DownloadHandlerFile(_tempFilePath, true);
  42. handler.removeFileOnAbort = false;
  43. #else
  44. var handler = new DownloadHandlerFileRange(tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest);
  45. _downloadHandle = handler;
  46. #endif
  47. _webRequest.downloadHandler = handler;
  48. _webRequest.disposeDownloadHandlerOnDispose = true;
  49. if (fileLength > 0)
  50. _webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
  51. _webRequest.SendWebRequest();
  52. Status = ERequestStatus.InProgress;
  53. }
  54. public void Update()
  55. {
  56. if (Status == ERequestStatus.None)
  57. return;
  58. if (IsDone())
  59. return;
  60. DownloadProgress = _webRequest.downloadProgress;
  61. DownloadedBytes = _fileOriginLength + _webRequest.downloadedBytes;
  62. if (_webRequest.isDone == false)
  63. return;
  64. // 检查网络错误
  65. #if UNITY_2020_3_OR_NEWER
  66. RequestHttpCode = _webRequest.responseCode;
  67. if (_webRequest.result != UnityWebRequest.Result.Success)
  68. {
  69. RequestNetError = _webRequest.error;
  70. Status = ERequestStatus.Error;
  71. }
  72. else
  73. {
  74. Status = ERequestStatus.Success;
  75. }
  76. #else
  77. RequestHttpCode = _webRequest.responseCode;
  78. if (_webRequest.isNetworkError || _webRequest.isHttpError)
  79. {
  80. RequestNetError = _webRequest.error;
  81. Status = ERequestStatus.Error;
  82. }
  83. else
  84. {
  85. Status = ERequestStatus.Success;
  86. }
  87. #endif
  88. // 注意:下载断点续传文件发生特殊错误码之后删除文件
  89. if (Status == ERequestStatus.Error)
  90. {
  91. if (DownloadHelper.ClearFileResponseCodes != null)
  92. {
  93. if (DownloadHelper.ClearFileResponseCodes.Contains(RequestHttpCode))
  94. {
  95. if (File.Exists(_tempFilePath))
  96. File.Delete(_tempFilePath);
  97. }
  98. }
  99. }
  100. // 最终释放下载器
  101. DisposeWebRequest();
  102. }
  103. public void Abort()
  104. {
  105. DisposeWebRequest();
  106. if (IsDone() == false)
  107. {
  108. RequestNetError = "user abort";
  109. RequestHttpCode = 0;
  110. Status = ERequestStatus.Error;
  111. }
  112. }
  113. public bool IsDone()
  114. {
  115. if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
  116. return true;
  117. else
  118. return false;
  119. }
  120. public object GetRequestObject()
  121. {
  122. throw new System.NotImplementedException();
  123. }
  124. private void DisposeWebRequest()
  125. {
  126. if (_downloadHandle != null)
  127. {
  128. _downloadHandle.Cleanup();
  129. _downloadHandle = null;
  130. }
  131. if (_webRequest != null)
  132. {
  133. _webRequest.Dispose();
  134. _webRequest = null;
  135. }
  136. }
  137. }
  138. }