使用说明:
1)远端更新服务器目录
Package
|----list.txt
|----a.bundle
|----b.bundle
2)list.txt是更新列表文件
格式是
a.bundle|res/a.bundle
b.bundle|res/b.bundle
(a.bundle是要拼的url,res/a.bundle是要被写在cache的路径)
3)使用代码
var downloader = gameObject.GetComponent<PatchFileDownloader>(); if (null == downloader) { downloader = gameObject.AddComponent<PatchFileDownloader>(); } downloader.OnDownLoading = (n, c, file, url) => { Debug.Log(url); }; downloader.OnDownLoadOver =(ret)=>{ Debug.Log("OnDownLoadOver "+ret.ToString()); }; downloader.Download("http://192.168.1.103:3080/Package/", "list.txt");
//更新文件下载器
using System; using UnityEngine; using System.Collections; using System.IO; using System.Collections.Generic; //更新文件下载器 public class PatchFileDownloader : MonoBehaviour { //每个更新文件的描述信息 protected class PatchFileInfo { // str 的格式是 url.txt|dir/a.txt url.txt是要拼的url,dir/a.txt是要被写在cache的路径 public PatchFileInfo(string str) { Parse(str); } //解析 protected virtual void Parse(string str) { var val = str.Split(‘|‘); if (1 == val.Length) { PartialUrl = val[0]; RelativePath = val[0]; } else if (2 == val.Length) { PartialUrl = val[0]; RelativePath = val[1]; } else { Debug.Log("PatchFileInfo parse error"); } } //要被拼接的URL public string PartialUrl { get; private set; } //文件相对目录 public string RelativePath { get; private set; } } public delegate void DelegateLoading(int idx, int total, string bundleName, string path); public delegate void DelegateLoadOver(bool success); //正在下载中回掉 public DelegateLoading OnDownLoading; //下载完成回掉 public DelegateLoadOver OnDownLoadOver; //总共要下载的bundle个数 private int mTotalBundleCount = 0; //当前已下载的bundle个数 private int mBundleCount = 0; //开始下载 public void Download(string url,string dir) { mBundleCount = 0; mTotalBundleCount = 0; StartCoroutine(CoDownLoad(url, dir)); } //下载Coroutine private IEnumerator CoDownLoad(string url, string dir) { //先拼接URL string fullUrl = Path.Combine(url, dir); //获得要更新的文件列表 List<string> list = new List<string>(); //先下载列表文件 using (WWW www = new WWW(fullUrl)) { yield return www; if (www.error != null) { //下载失败 if (null != OnDownLoadOver) { try { OnDownLoadOver(false); } catch (Exception e) { Debug.LogError(e.Message); } } Debugger.LogError(string.Format("Read {0} failed: {1}", fullUrl, www.error)); yield break; } //读取字节 ByteReader reader = new ByteReader(www.bytes); //读取每一行 while (reader.canRead) { list.Add(reader.ReadLine()); } if (null != www.assetBundle) { www.assetBundle.Unload(true); } www.Dispose(); } //收集所有需要下载的 var fileList = new List<PatchFileInfo>(); for (int i = 0; i < list.Count; i++) { var info = new PatchFileInfo(list[i]); if (!CheckNeedDownload(info)) { continue; } fileList.Add(info); } mTotalBundleCount = fileList.Count; //开始下载所有文件 for (int i = 0; i < fileList.Count; i++) { var info = fileList[i]; var fileUrl = Path.Combine(url, info.PartialUrl); StartCoroutine(CoDownloadAndWriteFile(fileUrl, info.RelativePath)); } //检查是否下载完毕 StartCoroutine(CheckLoadFinish()); } //检查是否该下载 protected virtual bool CheckNeedDownload(PatchFileInfo info) { return true; } //下载并写入文件 private IEnumerator CoDownloadAndWriteFile(string url,string filePath) { var fileName = Path.GetFileName(filePath); using (WWW www = new WWW(url)) { yield return www; if (www.error != null) { Debugger.LogError(string.Format("Read {0} failed: {1}", url, www.error)); yield break; } var writePath = CreateDirectoryRecursive(filePath) + "/" + fileName; FileStream fs1 = File.Open(writePath, FileMode.OpenOrCreate); fs1.Write(www.bytes, 0, www.bytesDownloaded); fs1.Close(); //Debug.Log("download " + writePath); if (null != www.assetBundle) { www.assetBundle.Unload(true); } www.Dispose(); mBundleCount++; if (null != OnDownLoading) { try { OnDownLoading(mBundleCount, mTotalBundleCount, writePath, url); } catch (Exception e) { Debug.LogError(e.Message); } } } } //递归创建文件夹 public static string CreateDirectoryRecursive(string relativePath) { var list = relativePath.Split(‘/‘); var temp = Application.temporaryCachePath; for (int i=0;i<list.Length-1;i++) { var dir = list[i]; if (string.IsNullOrEmpty(dir)) { continue; } temp += "/" + dir; if (!Directory.Exists(temp)) { Directory.CreateDirectory(temp); } } return temp; } //清空某个目录 public static void CleanDirectory(string relativePath) { var fallPath = Path.Combine(Application.temporaryCachePath, relativePath); if (string.IsNullOrEmpty(relativePath)) { Caching.CleanCache(); return; } var dirs = Directory.GetDirectories(fallPath); var files = Directory.GetFiles(fallPath); foreach (var file in files) { File.Delete(file); } foreach (var dir in dirs) { Directory.Delete(dir, true); } Debug.Log("CleaDirectory " + fallPath); } //检查是否已经下载完毕 IEnumerator CheckLoadFinish() { while (mBundleCount < mTotalBundleCount) { yield return null; } if (null != OnDownLoadOver) { try { OnDownLoadOver(true); } catch (Exception e) { Debug.LogError(e.Message); } } } }
时间: 2024-11-17 13:46:48