Unity下载文件的方式小结

1 UnityWebRequest下载

unity自带的下载方式,优点很明显:封装很好,使用简便,与unity使用兼容性很好且跨平台问题少;对应的缺点:扩展性差.

1.1 存在内存中供程序使用或者下载一些小文件

例子:

   public IEnumerator DownloadFile(string url, string contentName)
    {
        string downloadFileName = "";
#if UNITY_EDITOR
        downloadFileName = Path.Combine(Application.dataPath, contentName);
#elif UNITY_ANDROID
        downloadFileName = Path.Combine(Application.persistentDataPath, contentName);
#endif
        using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
        {
            yield return webRequest.SendWebRequest();
            if (webRequest.isNetworkError)
            {
                Debug.LogError(webRequest.error);
            }
            else
            {
                DownloadHandler fileHandler = webRequest.downloadHandler;
                using (MemoryStream memory = new MemoryStream(fileHandler.data))
                {
                    byte[] buffer = new byte[1024 * 1024];
                    FileStream file = File.Open(downloadFileName, FileMode.OpenOrCreate);
                    int readBytes;
                    while ((readBytes = memory.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        file.Write(buffer, 0, readBytes);
                    }
                    file.Close();
                }
            }
        }
    }

  

1.2 新版unity新增了DownloadHandlerFile的支持函数,可以直接将文件下载到外存

例子:

 public IEnumerator DownloadVideoFile01(Uri uri, string downloadFileName, Slider sliderProgress )
    {
        using (UnityWebRequest downloader = UnityWebRequest.Get(uri))
        {
            downloader.downloadHandler = new DownloadHandlerFile(downloadFileName);

            print("开始下载");
            downloader.SendWebRequest();
            print("同步进度条");
            while (!downloader.isDone)
            {
                //print(downloader.downloadProgress);
                sliderProgress.value = downloader.downloadProgress;
                sliderProgress.GetComponentInChildren<Text>().text = (downloader.downloadProgress* 100).ToString("F2") + "%";
                yield return null;
            }

            if (downloader.error != null)
            {
                Debug.LogError(downloader.error);
            }
            else
            {
                print("下载结束");
                sliderProgress.value = 1f;
                sliderProgress.GetComponentInChildren<Text>().text = 100.ToString("F2") + "%";
            }
        }
    }

 

2 C# http下载

.net的http下载很灵活,不同的下载方式,如流式下载,分块下载,还是断点续传等等,可扩展性非常强;但是因为是.net框架,有时发布到其他平台会有莫名其妙的bug;

送上封装好的代码,转载的代码,找不到出处,希望原作见谅:PS:很好用

   /// <summary>
    /// 下载器
    /// </summary>
    public class Downloader
    {
        /// <summary>
        /// 取消下载的错误描述
        /// </summary>
        const string CANCELLED_ERROR = "Cancelled";

        /// <summary>
        /// 重写的WebClient类
        /// </summary>
        class DownloadWebClient : WebClient
        {
            readonly int _timeout;
            public DownloadWebClient(int timeout = 60)
            {
                if (null == ServicePointManager.ServerCertificateValidationCallback)
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                }

                _timeout = timeout * 1000;
            }

            protected override WebRequest GetWebRequest(Uri address)
            {
                HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
                request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
                //request.ProtocolVersion = HttpVersion.Version10;
                request.Timeout = _timeout;
                request.ReadWriteTimeout = _timeout;
                request.Proxy = null;
                return request;
            }

            protected override WebResponse GetWebResponse(WebRequest request)
            {
                return base.GetWebResponse(request);
            }

            private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                //总是接受,通过Https验证
                return true;
            }
        }

        DownloadWebClient _client;

        bool _isDone;

        /// <summary>
        /// 是否操作完成
        /// </summary>
        public bool isDone
        {
            get
            {
                return _isDone;
            }
        }

        float _progress;

        /// <summary>
        /// 操作进度
        /// </summary>
        public float progress
        {
            get
            {
                return _progress;
            }
        }

        string _error;

        /// <summary>
        /// 错误信息
        /// </summary>
        public string error
        {
            get
            {
                return _error;
            }
        }

        long _totalSize;

        /// <summary>
        /// 文件总大小
        /// </summary>
        public long totalSize
        {
            get
            {
                return _totalSize;
            }
        }

        long _loadedSize;

        /// <summary>
        /// 已完成大小
        /// </summary>
        public long loadedSize
        {
            get
            {
                return _loadedSize;
            }
        }

        /// <summary>
        /// 是否已销毁
        /// </summary>
        public bool isDisposeed
        {
            get { return _client == null ? true : false; }
        }


        readonly string _savePath;

        /// <summary>
        /// 文件的保存路径
        /// </summary>
        public string savePath
        {
            get { return _savePath; }
        }

        readonly bool _isAutoDeleteWrongFile;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url">下载的文件地址</param>
        /// <param name="savePath">文件保存的地址</param>
        /// <param name="isAutoDeleteWrongFile">是否自动删除未下完的文件</param>
        public Downloader(string url, string savePath, bool isAutoDeleteWrongFile = true)
        {
            _isAutoDeleteWrongFile = isAutoDeleteWrongFile;
            _savePath = savePath;
            _client = new DownloadWebClient();
            _client.DownloadProgressChanged += OnDownloadProgressChanged;
            _client.DownloadFileCompleted += OnDownloadFileCompleted;

            Uri uri = new Uri(url);
            _client.DownloadFileAsync(uri, savePath);
        }

        /// <summary>
        /// 销毁对象,会停止所有的下载
        /// </summary>
        public void Dispose()
        {
            if (null != _client)
            {
                _client.CancelAsync();
            }
        }

        void ClearClient()
        {
            _client.DownloadProgressChanged -= OnDownloadProgressChanged;
            _client.DownloadFileCompleted -= OnDownloadFileCompleted;
            _client.Dispose();
            _client = null;
        }

        /// <summary>
        /// 下载文件完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            ClearClient();

            _isDone = true;

            if (e.Cancelled || e.Error != null)
            {
                _error = e.Error == null ? CANCELLED_ERROR : e.Error.Message;
                if (_isAutoDeleteWrongFile)
                {
                    try
                    {
                        //删除没有下载完成的文件
                        File.Delete(_savePath);
                    }
                    catch
                    {

                    }
                }
            }
        }

        /// <summary>
        /// 下载进度改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            _loadedSize = e.BytesReceived;
            _totalSize = e.TotalBytesToReceive;
            if (0 == _totalSize)
            {
                _progress = 0;
            }
            else
            {
                _progress = _loadedSize / (float)_totalSize;
            }

        }
    }

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值