zoukankan      html  css  js  c++  java
  • Unity3D 更新文件下载器

    使用说明:

    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);
                }
            }
        }
    }
  • 相关阅读:
    [网络流24题]餐巾计划问题
    [网络流24题]方格取数问题
    [网络流24题]试题库问题
    [网络流24题]最长递增子序列问题
    [网络流24题]圆桌问题
    [网络流24题]魔术球问题
    51nod1462 树据结构
    51nod1053 最大M子段和 V2
    51nod1026 矩阵中不重复的元素 V2
    BZOJ3832: [Poi2014]Rally
  • 原文地址:https://www.cnblogs.com/mrblue/p/5571158.html
Copyright © 2011-2022 走看看