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);
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM