DataFileUtil.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. using System;
  2. using System.IO;
  3. using UnityEngine;
  4. using System.Text;
  5. using System.Collections;
  6. using UnityEngine.Networking;
  7. using System.Threading.Tasks;
  8. using System.Threading;
  9. using System.Collections.Generic;
  10. namespace XRTool.Util
  11. {
  12. /// <summary>
  13. /// 文件工具类
  14. /// 下载,写入文件,断点续传,边下边存
  15. /// 遍历,拷贝文件
  16. /// 获取文件的MD5等
  17. /// </summary>
  18. public class DataFileUtil
  19. {
  20. /// <summary>
  21. /// 预估的写入文件的速度,与真实速度无关,仅仅是模拟评估,预计写入用时
  22. /// </summary>
  23. public const float WriteSpeed = 1024 * 1024 * 150f;
  24. ///// <summary>
  25. ///// 写入缓存的大小,如果越小,可能会引起卡顿(频繁访问数据)
  26. ///// </summary>
  27. //public const int CacheSave = 1024 * 1024 * 2;
  28. /// <summary>
  29. /// 图片格式
  30. /// </summary>
  31. public static string[] TexturesType = new string[] { "BMP", "EXR", "GIF", "HDR", "IFF", "JPG", "PICT", "PNG", "PSD", "TGA", "TIFF" };
  32. /// <summary>
  33. /// 视频格式
  34. /// </summary>
  35. public static string[] MoviesType = new string[] { "MOV", "MPG", "MP4", "AVI", "ASF" };
  36. /// <summary>
  37. /// 音频格式
  38. /// </summary>
  39. public static string[] AudiosType = new string[] { "ACC", "AIFF", "IT", "MOD", "MPEG", "OGGVORBIS", "S3M",
  40. "AIF", "WAV", "MP3", "OGG","XM","XMA","VAG","AUDIOQUEUE" };
  41. public static int maxTryCount = 5;
  42. /// <summary>
  43. /// 下载数据到本地,并将下载的数据返回给到上层应用
  44. /// 此下载仅应用于可缓存的资源,图片文本等下载,大文件的下载请使用断点下载
  45. /// </summary>
  46. /// <param name="url"></param>
  47. /// <param name="path"></param>
  48. /// <param name="downLoadProcess"></param>
  49. /// <param name="completeData"></param>
  50. /// <param name="isAsync"></param>
  51. /// <returns></returns>
  52. public static IEnumerator DownLoadData(string url, string path,
  53. Action<string, UnityWebRequest> completeData, DownloadHandler hander = null, Action<float, float> downLoadProcess=null, bool isAsync = false)
  54. {
  55. bool isDowning = true;
  56. UnityWebRequest web = null;
  57. //DownloadHandlerTexture
  58. yield return RequestDownData(url, (string error, UnityWebRequest req) =>
  59. {
  60. ///下载成功后开始拷贝数据到本地
  61. if (string.IsNullOrEmpty(error))
  62. {
  63. ///同步存储方法
  64. if (!isAsync)
  65. {
  66. SaveDataToFile(path, req.downloadHandler.data);
  67. downLoadProcess?.Invoke(req.downloadHandler.data.Length, 1);
  68. completeData?.Invoke(path, req);
  69. return;
  70. }
  71. else
  72. {
  73. web = req;
  74. ///此时,已下载到内存中,但是仍未缓存至内存中,内存数据可用
  75. completeData?.Invoke(null, req);
  76. }
  77. }
  78. else
  79. {
  80. ///下载出错
  81. completeData?.Invoke(null, null);
  82. //UnityLog.Instance.LogError(error);
  83. }
  84. isDowning = false;
  85. }, hander, (float allLeng, float process) =>
  86. {
  87. ///下载的进度,1/1.2,给存储留进度条显示,约等于0.89
  88. downLoadProcess?.Invoke(allLeng, process / 1.12f);
  89. });
  90. ///等待下载完成,此下载是下载到内存中
  91. while (isDowning)
  92. {
  93. yield return 0;
  94. }
  95. if (isAsync && web != null)
  96. {
  97. //completeData?.Invoke(true, data);
  98. yield return SaveDataToFile(path, web.downloadHandler.data, (float saveProcess) =>
  99. {
  100. ///更新存储文件的进度
  101. downLoadProcess?.Invoke(web.downloadHandler.data.Length, saveProcess * 0.1f + 0.9f);
  102. }, (bool isSuccess, string filePath) =>
  103. {
  104. completeData?.Invoke(filePath, web);
  105. });
  106. }
  107. web.Dispose();
  108. }
  109. //public static IEnumerator DownLoadData(string url, string path, Action<string, UnityWebRequest> completeData,
  110. // DownloadHandler hander = null, Action<float, float> downLoadProcess = null, bool isAsync = false)
  111. //{
  112. // bool isDowning = true;
  113. // UnityWebRequest web = null;
  114. // //DownloadHandlerTexture
  115. // yield return RequestDownData(url, (string error, UnityWebRequest req) =>
  116. // {
  117. // ///下载成功后开始拷贝数据到本地
  118. // if (string.IsNullOrEmpty(error))
  119. // {
  120. // ///同步存储方法
  121. // if (!isAsync)
  122. // {
  123. // SaveDataToFile(path, req.downloadHandler.data);
  124. // downLoadProcess?.Invoke(req.downloadHandler.data.Length, 1);
  125. // completeData?.Invoke(path, req);
  126. // return;
  127. // }
  128. // else
  129. // {
  130. // web = req;
  131. // ///此时,已下载到内存中,但是仍未缓存至内存中,内存数据可用
  132. // completeData?.Invoke(null, req);
  133. // }
  134. // }
  135. // else
  136. // {
  137. // ///下载出错
  138. // completeData?.Invoke(null, null);
  139. // //UnityLog.Instance.LogError(error);
  140. // }
  141. // isDowning = false;
  142. // }, hander, (float allLeng, float process) =>
  143. // {
  144. // ///下载的进度,1/1.2,给存储留进度条显示,约等于0.89
  145. // downLoadProcess?.Invoke(allLeng, process / 1.12f);
  146. // });
  147. // ///等待下载完成,此下载是下载到内存中
  148. // while (isDowning)
  149. // {
  150. // yield return 0;
  151. // }
  152. // if (isAsync && web != null)
  153. // {
  154. // //completeData?.Invoke(true, data);
  155. // yield return SaveDataToFile(path, web.downloadHandler.data, (float saveProcess) =>
  156. // {
  157. // ///更新存储文件的进度
  158. // downLoadProcess?.Invoke(web.downloadHandler.data.Length, saveProcess * 0.1f + 0.9f);
  159. // }, (bool isSuccess, string filePath) =>
  160. // {
  161. // completeData?.Invoke(filePath, web);
  162. // });
  163. // }
  164. //}
  165. /// <summary>
  166. /// 请求后台数据接口
  167. /// </summary>
  168. /// <returns></returns>
  169. public static IEnumerator RequestData(string url, Action<string> reqComplete, bool isPost = true,
  170. Dictionary<string, string> header = null, Dictionary<string, string> form = null, Action complete = null)
  171. {
  172. ///表单
  173. using (UnityWebRequest web = isPost ? UnityWebRequest.Post(url, form) : UnityWebRequest.Get(url))
  174. {
  175. if (header != null)
  176. {
  177. foreach (var item in header)
  178. {
  179. web.SetRequestHeader(item.Key, item.Value);
  180. }
  181. }
  182. yield return web.SendWebRequest();
  183. if (web.isNetworkError || web.isHttpError)
  184. {
  185. UnityLog.Instance.LogError(web.error);
  186. reqComplete?.Invoke(null);
  187. complete?.Invoke();
  188. yield break;
  189. }
  190. else
  191. {
  192. reqComplete?.Invoke(web.downloadHandler.text);
  193. complete?.Invoke();
  194. }
  195. }
  196. }
  197. /// <summary>
  198. /// 获取资源的大小
  199. /// </summary>
  200. /// <param name="url"></param>
  201. /// <param name="getLen"></param>
  202. /// <returns></returns>
  203. public static IEnumerator GetDataSize(string url, Action<long> getLen)
  204. {
  205. var headRequest = UnityWebRequest.Head(url);
  206. yield return headRequest.SendWebRequest();
  207. getLen?.Invoke(long.Parse(headRequest.GetResponseHeader("Content-Length")));
  208. headRequest.Dispose();
  209. }
  210. /// <summary>
  211. /// 异步下载,此下载不再判断文件是否存在,直接走下载方法
  212. /// 请在传值时先对DownInfo进行初始化判断
  213. /// </summary>
  214. /// <returns></returns>
  215. //public static IEnumerator DownLoadDataAsync(DownInfo info, int count = 0)
  216. //{
  217. // float watieTime = 0;
  218. // while (Application.internetReachability == NetworkReachability.NotReachable)
  219. // {
  220. // UnityLog.Instance.LogError("No Internet Connect");
  221. // yield return new WaitForSeconds(watieTime);
  222. // watieTime += 0.1f;
  223. // if (watieTime > 1)
  224. // {
  225. // watieTime = 1;
  226. // }
  227. // }
  228. // DownInfoHandler handler = new DownInfoHandler(info);
  229. // Dictionary<string, string> form = new Dictionary<string, string>();
  230. // form.Add("appId", info.id.ToString());
  231. // form.Add("searchId", info.searchId.ToString());
  232. // form.Add("recommendId", info.recommendId.ToString());
  233. // form.Add("word", info.word == null ? "" : info.word);
  234. // using (UnityWebRequest web = UnityWebRequest.Post(info.server, form))
  235. // {
  236. // handler.SetWebRequest(web, info.lastVersionSize);
  237. // web.disposeDownloadHandlerOnDispose = true;
  238. // web.downloadHandler = handler;
  239. // foreach (var item in UrlMgr.Instance.Header)
  240. // {
  241. // web.SetRequestHeader(item.Key, item.Value);
  242. // }
  243. // ///请求指定的长度
  244. // web.SetRequestHeader("Range", info.downloadedFileLen.ToString());
  245. // UnityLog.Instance.Log("bytes=" + info.downloadedFileLen + "-" + info.totalSize, 3);
  246. // yield return web.SendWebRequest();
  247. // if (web.isNetworkError || web.isHttpError)
  248. // {
  249. // if (count < maxTryCount)
  250. // {
  251. // UnityLog.Instance.LogError(info.fileName + "down error ,try again: " + count + web.error + "bytes=" + info.downloadedFileLen + "-" + info.totalSize);
  252. // count++;
  253. // web.Dispose();
  254. // handler.ErrorDispose(false);
  255. // yield return new WaitForSeconds(0.1f);
  256. // yield return DownLoadDataAsync(info, count);
  257. // yield break;
  258. // }
  259. // UnityLog.Instance.LogError(web.error + "bytes=" + info.downloadedFileLen + "-" + info.totalSize);
  260. // handler.ErrorDispose();
  261. // }
  262. // else
  263. // {
  264. // }
  265. // web.Dispose();
  266. // }
  267. //}
  268. /// <summary>
  269. /// 断点续传/下载,边下边存
  270. /// 适用于大文件下载。如果是简单的文本或者图片,尽量不要使用此接口
  271. /// </summary>
  272. /// <param name="url">目标地址</param>
  273. /// <param name="path">本地文件路径</param>
  274. /// <param name="downLoadProcess">下载进度</param>
  275. /// <param name="complete">返回下载的状态,成功或失败,成功后返回改文件的路径</param>
  276. /// <returns></returns>
  277. //public static IEnumerator DownLoadDataAsync(string url, string path, Action<float, float> downLoadProcess, Action<bool, string> complete)
  278. //{
  279. // ///获取文件的大小
  280. // FileStream fs = null;
  281. // long curLen = 0;
  282. // ///文件读写异常,返回错误
  283. // try
  284. // {
  285. // string dir = Path.GetDirectoryName(path);
  286. // if (!Directory.Exists(dir))
  287. // {
  288. // Directory.CreateDirectory(dir);
  289. // }
  290. // fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
  291. // curLen = fs.Length;
  292. // UnityLog.Instance.Log("当前文件大小" + curLen, 2);
  293. // }
  294. // catch (Exception ex)
  295. // {
  296. // if (fs != null)
  297. // {
  298. // fs.Close();
  299. // }
  300. // UnityLog.Instance.LogError(path + ex.ToString());
  301. // downLoadProcess.Invoke(curLen, 0);
  302. // complete?.Invoke(false, ex.ToString());
  303. // yield break;
  304. // }
  305. // ///请求获取文件的大小
  306. // ///已下载完成,无需再次下载
  307. // long totalLength = 0;
  308. // yield return GetDataSize(url, (size) =>
  309. // {
  310. // totalLength = size;
  311. // });
  312. // ///当前文件的大小和云端文件大小一致
  313. // ///理论上不会出现这个问题
  314. // if (curLen == totalLength)
  315. // {
  316. // fs.Close();
  317. // downLoadProcess.Invoke(totalLength, 1);
  318. // complete?.Invoke(true, path);
  319. // yield break;
  320. // }
  321. // ///文件异常,删除文件,重新下载
  322. // ///理论上不会出现这个问题
  323. // else if (curLen > totalLength)
  324. // {
  325. // UnityLog.Instance.LogError("文件大小异常" + curLen + "__" + totalLength);
  326. // fs.Close();
  327. // File.Delete(path);
  328. // fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
  329. // curLen = fs.Length;
  330. // }
  331. // fs.Seek(curLen, SeekOrigin.Begin);
  332. // bool isSuccess = true;
  333. // yield return RequestDownData(url, (byte[] data, int len) =>
  334. // {
  335. // if (isSuccess && data.Length > 0)
  336. // {
  337. // try
  338. // {
  339. // fs.Write(data, 0, len);
  340. // fs.Flush();
  341. // curLen += len;
  342. // downLoadProcess?.Invoke(curLen, curLen * 1f / totalLength);
  343. // }
  344. // catch (Exception ex)
  345. // {
  346. // UnityLog.Instance.LogError(ex.ToString());
  347. // isSuccess = false;
  348. // return;
  349. // }
  350. // }
  351. // else
  352. // {
  353. // ///理论上不会出现这个问题,除非出现异常情况如内存不足等
  354. // //complete?.Invoke(isSuccess, path);
  355. // UnityLog.Instance.LogError("Down Error:" + url);
  356. // }
  357. // }, totalLength, curLen);
  358. // fs.Close();
  359. // downLoadProcess.Invoke(totalLength, 1);
  360. // complete?.Invoke(isSuccess, path);
  361. //}
  362. /// <summary>
  363. /// Get请求下载数据,断点下载,边下载边返回数据进行存储
  364. /// </summary>
  365. /// <param name="url">url</param>
  366. /// <param name="downData">返回获取的数据</param>
  367. /// <param name="allLen">文件的总大小</param>
  368. /// <param name="downedLength">已下载的数据</param>
  369. /// <returns></returns>
  370. //public static IEnumerator RequestDownData(string url, Action<byte[], int> downData, long allLen, long downedLength = 0)
  371. //{
  372. // //float downTime = Time.time;
  373. // UnityWebRequest web = UnityWebRequest.Get(url);
  374. // web.disposeDownloadHandlerOnDispose = true;
  375. // DataDownLoadHandler ddh = new DataDownLoadHandler();
  376. // web.downloadHandler = ddh;
  377. // ddh.OnReceiveData += downData;
  378. // ///请求指定的长度
  379. // web.SetRequestHeader("Range", "bytes=" + downedLength + "-" + allLen);
  380. // yield return web.SendWebRequest();
  381. // web.Dispose();
  382. //}
  383. /// <summary>
  384. /// 从URl下载指定的资源
  385. /// </summary>
  386. /// <param name="url">资源的地址,可以是网络路径,也可以是本地文件路径</param>
  387. /// <param name="updateProcess">下载的进度,当前已下载文件大小,以及进度</param>
  388. /// <param name="complete"></param>
  389. /// <param name="form">请求的参数,如果为空代表Get请求,不为空代表Post请求</param>
  390. /// <returns></returns>
  391. public static IEnumerator RequestDownData(string url, Action<string, UnityWebRequest> complete, DownloadHandler hander = null, Action<float, float> updateProcess = null, WWWForm form = null)
  392. {
  393. UnityWebRequest web;
  394. Debug.Log("RequestDownData" + url);
  395. if (form == null)
  396. {
  397. web = UnityWebRequest.Get(url);
  398. }
  399. else
  400. {
  401. web = UnityWebRequest.Post(url, form);
  402. }
  403. if (hander != null)
  404. {
  405. web.downloadHandler = hander;
  406. }
  407. web.SendWebRequest();
  408. while (!web.isDone)
  409. {
  410. updateProcess?.Invoke(web.downloadedBytes, web.downloadProgress);
  411. yield return 0;
  412. }
  413. if (web.isDone)
  414. {
  415. updateProcess?.Invoke(web.downloadedBytes, 1);
  416. }
  417. if (web.isNetworkError || web.isHttpError)
  418. {
  419. complete?.Invoke(web.error, web);
  420. Debug.LogError(web.error+url);
  421. }
  422. else
  423. {
  424. complete?.Invoke(null, web);
  425. }
  426. web.Dispose();
  427. }
  428. /// <summary>
  429. /// 上传数据到服务端,并得到服务器返回的结果
  430. /// 与下面的RequestDownData类似,但是更新上传进度,适用于文件上传
  431. /// </summary>
  432. /// <param name="url"></param>
  433. /// <param name="form"></param>
  434. /// <param name="updateProcess"></param>
  435. /// <param name="complete"></param>
  436. /// <returns></returns>
  437. public static IEnumerator RequestUpLoadData(string url, WWWForm form, Action<float, float> updateProcess, Action<string, UnityWebRequest> complete)
  438. {
  439. UnityWebRequest web = UnityWebRequest.Post(url, form);
  440. web.SendWebRequest();
  441. while (!web.isDone)
  442. {
  443. updateProcess?.Invoke(web.uploadedBytes, web.uploadProgress);
  444. yield return 0;
  445. }
  446. if (web.isDone)
  447. {
  448. updateProcess?.Invoke(web.uploadedBytes, 1);
  449. }
  450. if (web.isNetworkError || web.isHttpError)
  451. {
  452. complete?.Invoke(web.error, web);
  453. }
  454. else
  455. {
  456. complete?.Invoke(null, web);
  457. }
  458. web.Dispose();
  459. }
  460. /// <summary>
  461. /// 是否是忽略的文件类型
  462. /// </summary>
  463. /// <param name="sug"></param>
  464. /// <returns></returns>
  465. public static bool isIgnoreExtension(string ignoreExtension, string suffix)
  466. {
  467. string[] igs = ignoreExtension.Split('|', ' ', ',');
  468. for (int i = 0; i < igs.Length; i++)
  469. {
  470. if (igs[i] == suffix)
  471. {
  472. return true;
  473. }
  474. }
  475. return false;
  476. }
  477. /// <summary>
  478. /// 保存文本文件到本地
  479. /// 同步方法
  480. /// </summary>
  481. public static bool SaveDataToFile(string path, string txt)
  482. {
  483. try
  484. {
  485. if (!string.IsNullOrEmpty(txt))
  486. {
  487. File.WriteAllText(path, txt);
  488. return true;
  489. }
  490. }
  491. catch (Exception ex)
  492. {
  493. UnityLog.Instance.LogError(path + ex.ToString());
  494. }
  495. return false;
  496. }
  497. /// <summary>
  498. /// 保存二进制字节文件到本地,同步方法
  499. /// </summary>
  500. /// <param name="path"></param>
  501. /// <param name="data"></param>
  502. public static bool SaveDataToFile(string path, byte[] data)
  503. {
  504. try
  505. {
  506. string dir = Path.GetDirectoryName(path);
  507. if (!Directory.Exists(dir))
  508. {
  509. Directory.CreateDirectory(dir);
  510. }
  511. FileStream fs = new FileStream(path, FileMode.Create);
  512. fs.Write(data, 0, data.Length);
  513. fs.Dispose();
  514. fs.Close();
  515. return true;
  516. }
  517. catch (Exception ex)
  518. {
  519. UnityLog.Instance.LogError(path + ex.ToString());
  520. }
  521. return false;
  522. }
  523. /// <summary>
  524. /// 异步保存文本文件
  525. /// </summary>
  526. /// <param name="path"></param>
  527. /// <param name="txt"></param>
  528. /// <param name="saveProcess"></param>
  529. /// <returns></returns>
  530. public static IEnumerator SaveDataToFile(string path, string txt, Action<float> saveProcess, Action<bool, string> onComplete)
  531. {
  532. yield return SaveDataToFile(path, Encoding.Default.GetBytes(txt), saveProcess, onComplete);
  533. }
  534. /// <summary>
  535. /// 保存二进制字节文件到本地,异步方法
  536. /// </summary>
  537. /// <param name="path"></param>
  538. /// <param name="data"></param>
  539. private static IEnumerator SaveDataToFile(string path, byte[] data, Action<float> saveProcess, Action<bool, string> onComplete)
  540. {
  541. bool isSuccess = false;
  542. if (data != null && data.Length > 0)
  543. {
  544. Task task = null;
  545. FileStream fs = null;
  546. float allData = data.Length;
  547. try
  548. {
  549. fs = new FileStream(path, FileMode.Create);
  550. task = fs.WriteAsync(data, 0, data.Length);
  551. isSuccess = true;
  552. }
  553. catch (Exception ex)
  554. {
  555. UnityLog.Instance.LogError(path + ex.ToString());
  556. path = ex.ToString();
  557. isSuccess = false;
  558. }
  559. float tmp = 0;
  560. float allTime = data.Length / WriteSpeed;
  561. ///预计存储完成的时间
  562. while (task != null && !task.IsCompleted)
  563. {
  564. if (tmp < allTime)
  565. {
  566. tmp += Time.deltaTime;
  567. }
  568. saveProcess?.Invoke(tmp / allTime);
  569. yield return 0;
  570. }
  571. saveProcess(1);
  572. fs.Dispose();
  573. fs.Close();
  574. }
  575. onComplete?.Invoke(isSuccess, path);
  576. }
  577. /// <summary>
  578. /// 广度优先,遍历文件
  579. /// </summary>
  580. /// <param name="path"></param>
  581. /// <param name="callBack"></param>
  582. public static void FindFileBreadth(string path, Action<string> callBack)
  583. {
  584. try
  585. {
  586. DirectoryInfo di = new DirectoryInfo(path);
  587. FileInfo[] fis = di.GetFiles();
  588. for (int i = 0; i < fis.Length; i++)
  589. {
  590. callBack?.Invoke(fis[i].FullName);
  591. }
  592. DirectoryInfo[] dis = di.GetDirectories();
  593. for (int j = 0; j < dis.Length; j++)
  594. {
  595. FindFileBreadth(dis[j].FullName, callBack);
  596. }
  597. }
  598. catch (Exception ex)
  599. {
  600. UnityLog.Instance.LogError(ex.ToString());
  601. }
  602. }
  603. /// <summary>
  604. /// 深度优先,遍历文件
  605. /// </summary>
  606. /// <param name="dir"></param>
  607. public static void FindFileByDepth(string dir, Action<string> callBack)
  608. {
  609. try
  610. {
  611. DirectoryInfo d = new DirectoryInfo(dir);
  612. FileSystemInfo[] fsinfos = d.GetFileSystemInfos();
  613. foreach (FileSystemInfo fsinfo in fsinfos)
  614. {
  615. if (fsinfo is DirectoryInfo)
  616. {
  617. FindFileByDepth(fsinfo.FullName, callBack);
  618. }
  619. else
  620. {
  621. callBack?.Invoke(fsinfo.FullName);
  622. }
  623. }
  624. }
  625. catch (Exception ex)
  626. {
  627. UnityLog.Instance.LogError(ex.ToString());
  628. }
  629. }
  630. /// <summary>
  631. /// 获取文件MD5值
  632. /// </summary>
  633. /// <param name="fileName">文件绝对路径</param>
  634. /// <returns>MD5值</returns>
  635. public static string GetMD5HashFromFile(string fileName)
  636. {
  637. try
  638. {
  639. FileStream file = new FileStream(fileName, FileMode.Open);
  640. System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  641. byte[] retVal = md5.ComputeHash(file);
  642. file.Close();
  643. StringBuilder sb = new StringBuilder();
  644. for (int i = 0; i < retVal.Length; i++)
  645. {
  646. sb.Append(retVal[i].ToString("x2"));
  647. }
  648. return sb.ToString();
  649. }
  650. catch (Exception ex)
  651. {
  652. throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
  653. }
  654. }
  655. /// <summary>
  656. /// 重命名文件
  657. /// </summary>
  658. /// <param name="file"></param>
  659. /// <param name="newFile"></param>
  660. public static void ReNameFile(string file, string newFile)
  661. {
  662. if (File.Exists(file))
  663. {
  664. try
  665. {
  666. string dir = Path.GetDirectoryName(newFile);
  667. if (!Directory.Exists(dir))
  668. {
  669. Directory.CreateDirectory(dir);
  670. }
  671. if (File.Exists(newFile))
  672. {
  673. File.Delete(newFile);
  674. }
  675. FileInfo info = new FileInfo(file);
  676. info.MoveTo(newFile);
  677. }
  678. catch (Exception ex)
  679. {
  680. UnityLog.Instance.LogError(file + " is error" + ex.ToString());
  681. }
  682. }
  683. }
  684. /// <summary>
  685. /// 删除文件
  686. /// </summary>
  687. /// <param name="file"></param>
  688. /// <param name="newFile"></param>
  689. public static void DelFile(string file)
  690. {
  691. UnityLog.Instance.Log(file + " is Del", 3);
  692. if (File.Exists(file))
  693. {
  694. try
  695. {
  696. File.Delete(file);
  697. }
  698. catch (Exception ex)
  699. {
  700. UnityLog.Instance.LogError(file + " is error" + ex.ToString());
  701. }
  702. }
  703. }
  704. /// <summary>
  705. /// 拷贝文件
  706. /// </summary>
  707. /// <param name="SourcePath"></param>
  708. /// <param name="DestinationPath"></param>
  709. /// <param name="overwriteexisting">是否覆盖</param>
  710. /// <returns></returns>
  711. public static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)
  712. {
  713. bool ret = false;
  714. try
  715. {
  716. SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\";
  717. DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\";
  718. if (Directory.Exists(SourcePath))
  719. {
  720. if (Directory.Exists(DestinationPath) == false)
  721. Directory.CreateDirectory(DestinationPath);
  722. foreach (string fls in Directory.GetFiles(SourcePath))
  723. {
  724. FileInfo flinfo = new FileInfo(fls);
  725. flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
  726. }
  727. foreach (string drs in Directory.GetDirectories(SourcePath))
  728. {
  729. DirectoryInfo drinfo = new DirectoryInfo(drs);
  730. if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false)
  731. ret = false;
  732. }
  733. }
  734. ret = true;
  735. }
  736. catch (Exception ex)
  737. {
  738. ret = false;
  739. UnityLog.Instance.LogError(ex.ToString());
  740. }
  741. return ret;
  742. }
  743. /// <summary>
  744. /// 文件是否是图片
  745. /// </summary>
  746. /// <param name="fileName"></param>
  747. /// <returns></returns>
  748. public static bool IsMoviesFile(string fileName)
  749. {
  750. if (!string.IsNullOrEmpty(fileName))
  751. {
  752. string exten = Path.GetExtension(fileName);
  753. return IsMediaType(exten.ToUpper(), MoviesType);
  754. }
  755. return false;
  756. }
  757. public static bool IsTextureFile(string fileName)
  758. {
  759. if (!string.IsNullOrEmpty(fileName))
  760. {
  761. string exten = Path.GetExtension(fileName);
  762. return IsMediaType(exten.ToUpper(), TexturesType);
  763. }
  764. return false;
  765. }
  766. /// <summary>
  767. /// 判断是否是音频文件
  768. /// MP3,WAV等
  769. /// </summary>
  770. /// <param name="fileName"></param>
  771. /// <returns></returns>
  772. public static bool IsAudioFile(string fileName)
  773. {
  774. if (!string.IsNullOrEmpty(fileName))
  775. {
  776. string exten = Path.GetExtension(fileName);
  777. return IsMediaType(exten.ToUpper(), AudiosType);
  778. }
  779. return false;
  780. }
  781. /// <summary>
  782. /// 是否是多媒体文件:图片,视频,音频
  783. /// </summary>
  784. /// <param name="fileName"></param>
  785. /// <param name="types"></param>
  786. /// <returns></returns>
  787. public static bool IsMediaType(string fileName, string[] types)
  788. {
  789. if (!string.IsNullOrEmpty(fileName) && types != null)
  790. {
  791. for (int i = 0; i < types.Length; i++)
  792. {
  793. if (TexturesType[i] == fileName)
  794. {
  795. return true;
  796. }
  797. }
  798. }
  799. return false;
  800. }
  801. /// <summary>
  802. /// 是否多媒体文件
  803. /// 音频,视频,图片
  804. /// </summary>
  805. /// <param name="fileName"></param>
  806. /// <returns></returns>
  807. public static bool IsMediaType(string fileName)
  808. {
  809. if (!string.IsNullOrEmpty(fileName))
  810. {
  811. string exten = Path.GetExtension(fileName);
  812. exten = exten.ToUpper();
  813. return IsMediaType(exten, TexturesType) || IsMediaType(exten, MoviesType) || IsMediaType(exten, AudiosType);
  814. }
  815. return false;
  816. }
  817. /// <summary>
  818. /// 是否存在某文件
  819. /// </summary>
  820. /// <param name="file"></param>
  821. /// <returns></returns>
  822. public static bool Exists(string file)
  823. {
  824. return File.Exists(file);
  825. }
  826. }
  827. }