DownloadHelper.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System;
  6. /// <summary>
  7. /// 下载器
  8. /// </summary>
  9. public class DownloadHelper : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 单例
  13. /// </summary>
  14. private static DownloadHelper _instance;
  15. /// <summary>
  16. /// 获得单例
  17. /// </summary>
  18. /// <returns>单例</returns>
  19. public static DownloadHelper GetInstance()
  20. {
  21. if (null == _instance)
  22. {
  23. GameObject obj = new GameObject("DownloadHelper");
  24. _instance = obj.AddComponent<DownloadHelper>();
  25. }
  26. return _instance;
  27. }
  28. /// <summary>
  29. /// Awake方法
  30. /// </summary>
  31. private void Awake()
  32. {
  33. _instance = this;
  34. }
  35. #region ==========> 资源批量下载临时变量
  36. /// <summary>
  37. /// url列表
  38. /// </summary>
  39. private List<string> _urls = new List<string>();
  40. /// <summary>
  41. /// 总数
  42. /// </summary>
  43. private int _count = 0;
  44. /// <summary>
  45. /// 当前索引
  46. /// </summary>
  47. private int _index = 0;
  48. /// <summary>
  49. /// 下载的总字节数
  50. /// </summary>
  51. private int _total = 0;
  52. /// <summary>
  53. /// 当前www
  54. /// </summary>
  55. private WWW _www;
  56. /// <summary>
  57. /// 是否中断
  58. /// </summary>
  59. private bool _breaking = false;
  60. /// <summary>
  61. /// cdn根路径
  62. /// </summary>
  63. private string _cdnroot = "http://";
  64. /// <summary>
  65. /// 当前WWW组件,用于监听单文件下载进度,有可能为空
  66. /// </summary>
  67. public WWW curWWW
  68. {
  69. get
  70. {
  71. return _www;
  72. }
  73. }
  74. /// <summary>
  75. /// 当前文件处理流程
  76. /// </summary>
  77. public float progress
  78. {
  79. get
  80. {
  81. return _www == null ? 0 : _www.progress;
  82. }
  83. }
  84. /// <summary>
  85. /// 递归下载
  86. /// </summary>
  87. /// <param name="progress">进程回调</param>
  88. /// <param name="complete">完成回调</param>
  89. /// <param name="onError">错误回调</param>
  90. private void DownLoadItem(ProgressCallback progress, CompleteCallback complete, ErrorCallback onError)
  91. {
  92. if (_breaking)
  93. {
  94. return;
  95. }
  96. string url = _urls[_index];
  97. DownLoad(_cdnroot, url, (token) =>
  98. {
  99. _index++;
  100. progress.Invoke(_index, _count, _total);
  101. if (_index >= _count)
  102. {
  103. complete.Invoke("complete!");
  104. }
  105. else
  106. {
  107. DownLoadItem(progress, complete, onError);
  108. }
  109. }, onError);
  110. }
  111. #endregion
  112. /// <summary>
  113. /// 下载资源列表
  114. /// </summary>
  115. /// <param name="cdnroot">cnd根目录</param>
  116. /// <param name="urls">url路径</param>
  117. /// <param name="progress">进程回调</param>
  118. /// <param name="complete">完成回调</param>
  119. /// <param name="onError">错误回调</param>
  120. public void DownLoadList(string cdnroot, List<string> urls, ProgressCallback progress, CompleteCallback complete, ErrorCallback onError)
  121. {
  122. _cdnroot = cdnroot;
  123. _breaking = false;
  124. _urls.Clear();
  125. _urls = urls;
  126. _count = urls.Count;
  127. _index = 0;
  128. _total = 0;
  129. DownLoadItem(progress, complete, onError);
  130. }
  131. /// <summary>
  132. /// 中断列表下载(仅适用于列表下载)
  133. /// </summary>
  134. public void Break()
  135. {
  136. _breaking = true;
  137. }
  138. /// <summary>
  139. /// 单文件下载
  140. /// </summary>
  141. /// <param name="cdnroot">cdn根路径</param>
  142. /// <param name="url">url路径</param>
  143. /// <param name="callback">完成回调</param>
  144. /// <param name="onError">错误回调</param>
  145. public void DownLoad(string cdnroot, string url, CompleteCallback callback, ErrorCallback onError)
  146. {
  147. _cdnroot = cdnroot;
  148. StartCoroutine(IDownload(url, callback, onError));
  149. }
  150. /// <summary>
  151. /// 协同
  152. /// </summary>
  153. /// <param name="url">url</param>
  154. /// <param name="callback">回调</param>
  155. /// <param name="onError">错误回调</param>
  156. /// <returns>协同句柄</returns>
  157. private IEnumerator IDownload(string url, CompleteCallback callback, ErrorCallback onError)
  158. {
  159. if (_www != null)
  160. {
  161. _www.Dispose();
  162. _www = null;
  163. }
  164. WWW w = new WWW(_cdnroot + url);
  165. _www = w;
  166. DateTime start = DateTime.Now;
  167. /*
  168. // 超时检测
  169. while (false == w.isDone)
  170. {
  171. if (DateTime.Now - start > TimeSpan.FromSeconds(Const.NetDefaultTimeOut / 1000))
  172. {
  173. onError("Time out!!");
  174. yield break;
  175. }
  176. else
  177. {
  178. yield return null;
  179. }
  180. }
  181. * */
  182. yield return w;
  183. if (w.error != null)
  184. {
  185. LogHelper.LogWarning(w.error);
  186. onError(w.error);
  187. }
  188. else
  189. {
  190. LogHelper.Log("[DownLoad]::" + url);
  191. CreateFile(FilePath(url), w.bytes);
  192. _total += w.size;
  193. callback("ok!");
  194. }
  195. }
  196. /// <summary>
  197. /// 创建文件
  198. /// </summary>
  199. /// <param name="path">路径</param>
  200. /// <param name="content">内容</param>
  201. public static void CreateFile(string path, byte[] content)
  202. {
  203. string dir = GetDirectoryByPath(path);
  204. if (!Directory.Exists(dir))
  205. {
  206. Directory.CreateDirectory(dir);
  207. }
  208. FileStream fs = new FileStream(path, FileMode.Create);
  209. fs.Write(content, 0, content.Length);
  210. fs.Flush();
  211. fs.Close();
  212. }
  213. /// <summary>
  214. /// 根据文件路径截取目录
  215. /// </summary>
  216. /// <param name="path">路径</param>
  217. /// <returns>目录</returns>
  218. public static string GetDirectoryByPath(string path)
  219. {
  220. string[] temps = path.Split('/');
  221. string dir = string.Empty;
  222. for (int i = 0; i < temps.Length - 1; i++)
  223. {
  224. dir += temps[i] + "/";
  225. }
  226. return dir;
  227. }
  228. /// <summary>
  229. /// 获得文件路径
  230. /// </summary>
  231. /// <param name="url">url</param>
  232. /// <returns>路径</returns>
  233. private string FilePath(string url)
  234. {
  235. return Application.persistentDataPath + "/" + url;
  236. }
  237. }
  238. /// <summary>
  239. /// 错误回调
  240. /// </summary>
  241. /// <param name="msg">错误消息</param>
  242. public delegate void ErrorCallback(string msg);
  243. /// <summary>
  244. /// 完成回调
  245. /// </summary>
  246. /// <param name="token">token</param>
  247. public delegate void CompleteCallback(object token);
  248. /// <summary>
  249. /// 进程回调
  250. /// </summary>
  251. /// <param name="index">当前索引</param>
  252. /// <param name="count">总数</param>
  253. /// <param name="total">总字节数</param>
  254. public delegate void ProgressCallback(int index, int count, int total);