using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking; namespace TModule.Runtime { public class DownloadRoutine { /// /// 下载路径 /// public string DownLoadUrl { get; set; } /// /// 文件保存路径 /// public string FileSavePath { get; set; } /// /// 是否空闲 /// public bool IsLeisure { get; set; } = true; /// /// 下载总大小 /// private long _totalSzie; public long TotalSize => _totalSzie; /// /// 已下载大小 /// private long _currentDownloadSize; public long CurrentDownloadSize => _currentDownloadSize; //停止下载 private bool _isStop; public bool IsStop { get => _isStop || #if UNITY_EDITOR !UnityEditor.EditorApplication.isPlaying #else !Application.isPlaying #endif ; set => _isStop = value; } public Action onDownloadOver; /// /// 下载中事件 下载进度 总大小 已下载大小 /// public Action onProgress; public Action onError; /// /// 开始下载 /// /// /// public async Task StartDownload(string url,string fileSavePath) { DownLoadUrl = url; FileSavePath = fileSavePath; IsStop = false; _currentDownloadSize = 0; IsLeisure = false; UnityWebRequest webRequest = UnityWebRequest.Head(DownLoadUrl); await webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError) { onError?.Invoke(webRequest.error); Debug.Log(webRequest.error); //出现错误 输出错误信息 } else { string info = webRequest.GetResponseHeader("Content-Length"); _totalSzie = long.Parse(info); await DownloadFile(); } } public void StopDownload() { IsStop = true; } public async Task ContinueDownload() { if (IsLeisure) return; IsStop = false; await DownloadFile(); } async Task DownloadFile() { string dirPath = Path.GetDirectoryName(FileSavePath); if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); using (FileStream fs = new FileStream(FileSavePath, FileMode.OpenOrCreate, FileAccess.Write,FileShare.ReadWrite)) { _currentDownloadSize = fs.Length; if (_currentDownloadSize < _totalSzie) { fs.Seek(_currentDownloadSize, SeekOrigin.Begin); UnityWebRequest request = UnityWebRequest.Get(DownLoadUrl); request.SetRequestHeader("Range", $"bytes={_currentDownloadSize}-"); request.SendWebRequest(); if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError) { onError?.Invoke(request.error); Debug.Log(request.error); //出现错误 输出错误信息 } else { long index = 0; while (_currentDownloadSize < _totalSzie) { if (IsStop) break; byte[] data = request.downloadHandler.data; if (data != null) { long length = data.Length - index; fs.Write(data, (int)index, (int)length); index += length; _currentDownloadSize += length; onProgress?.Invoke((float)Math.Round((double)_currentDownloadSize / _totalSzie,2), _totalSzie, _currentDownloadSize); if (_currentDownloadSize >= _totalSzie) { //下载完成 IsLeisure = true; onDownloadOver?.Invoke(); break; } } await Task.Yield(); } } } } } } }