UnityWebRequest下载网络资源,支持断点续传、多文件同时下载

今晚研究了下关于Unity中文件下载的断点续传功能,Unity已经封装了网络资源的下载API,当然也可以使用C#中的API进行资源下载。
    首先说一下断点续传的大概思路:
    1、下载一个文件时,向服务器发送下载请求,发送一个Range的报文,指定从文件数据的什么位置开始获取数据,把从服务器路径接收到的文件数据,用文件流操作按顺序写入到本地临时文件流,当中断下载时,保存已下载的临时文件数据,释放文件流操作和下载请求。
    2、当再次进行下载时,用文件流读取本地已下载的临时文件,这时向服务器发送下载请求,把当前临时文件的大小作为Range报文的数据发送给服务器,此时就可以从上次下载的位置继续进行数据下载。这里注意的是,文件流的写入位置要设置为之前临时文件的最后,即Position等于临时文件的大小,这样才会将新的文件数据与之前的结合起来。
    3、当文件的全部数据都下载完成时,将临时文件重命名为真正的文件。

    然后说一下多文件同时下载的逻辑:多文件下载就是在单文件下载的基础上,每一个下载请求都是独立进行的,这就类似于多线程并发操作,需要注意的是多个下载连接会共同占用网络带宽,每个文件的下载速度都会降低。

    使用C#源生的API下载网络资源,基本上要使用到多线程下载机制,而Unity5.3以后的版本中带了一个UnityWebRequest的API,发现这个API可以真牛逼,应该完全可以代替WWW的所有功能(自己吹的牛逼……)
这个UnityWebRequest可以下载资源、上传数据、获取下载进度、中止下载等等,而且是在Unity的主线程中进行的。
下面简单说明下载操作:

 

    //下载的协程
    public IEnumerator StartDownload(string url, string savePath)
    {
        _DownloadHandler loadHandler = new _DownloadHandler(savePath);
        UnityWebRequest request = UnityWebRequest.Get(url);
        request.chunkedTransfer = true;
        request.disposeDownloadHandlerOnDispose = true;
        request.SetRequestHeader("Range", "bytes = " + loadHandler.DownedLength + "-"); //断点续传设置读取文件数据流开始索引,成功会返回206

        yield return request.Send(); //协程操作
    }//下载的协程
    public IEnumerator StartDownload(string url, string savePath)
    {
        _DownloadHandler loadHandler = new _DownloadHandler(savePath);
        UnityWebRequest request = UnityWebRequest.Get(url);
        request.chunkedTransfer = true;
        request.disposeDownloadHandlerOnDispose = true;
        request.SetRequestHeader("Range", "bytes = " + loadHandler.DownedLength + "-"); //断点续传设置读取文件数据流开始索引,成功会返回206

        yield return request.Send(); //协程操作
    }

 

 

 

以上是下载资源的主要操作,而数据处理和回调使用的是UnityWebRequest的downloadHandler属性,这个属性类型是DownloadHandler,因此需要我们自定义一个类集成DownloadHandler,然后重写里面的虚方法。注意里面的虚方法大部分都是回调类型的,也就是说都是由UnityWebRequest在下载过程中主动调用的,例如virtual void CompleteContent()方法是完成下载时的触发的回调,virtual void ReceiveContentLength(int contentLength)是刚开始下载时接收到整个文件的大小的回调,virtual bool ReceiveData(byte[] data, int dataLength)是下载中不断接收到文件数据的回调,等等。

我也不多说了,直接给分享简单的下载框架,主要功能只有两个脚本,一看遍明白了
https://download.csdn.net/download/u010377179/10257649

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Unity 2022中实现文件下载支持断点续传,同时支持GUI进度显示可以使用UnityWebRequest来实现。以下是一个简单的示例: ``` public class DownloadManager : MonoBehaviour { private UnityWebRequest request; private string savePath; private long fileSize; private long bytesDownloaded; private bool isDownloading; // GUI进度条相关 private float progress; private Rect progressRect = new Rect(50, 50, 200, 20); public void Download(string url, string savePath) { if (isDownloading) return; this.savePath = savePath; request = UnityWebRequest.Head(url); request.SendWebRequest(); StartCoroutine(GetFileSize()); } IEnumerator GetFileSize() { while (!request.isDone) yield return null; if (request.result != UnityWebRequest.Result.Success) { Debug.LogError("获取文件大小失败!"); yield break; } fileSize = long.Parse(request.GetResponseHeader("Content-Length")); if (File.Exists(savePath)) { FileInfo fileInfo = new FileInfo(savePath); bytesDownloaded = fileInfo.Length; request = UnityWebRequest.Get(request.uri.ToString()); request.SetRequestHeader("Range", "bytes=" + bytesDownloaded + "-"); } else { request = UnityWebRequest.Get(request.uri.ToString()); } request.downloadHandler = new DownloadHandlerBuffer(); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError("下载文件失败!"); yield break; } isDownloading = true; // 启动协程来写入文件 StartCoroutine(WriteToFile()); } IEnumerator WriteToFile() { using (FileStream fs = new FileStream(savePath, FileMode.Append)) { byte[] data = request.downloadHandler.data; fs.Write(data, 0, data.Length); bytesDownloaded += data.Length; while (isDownloading) { yield return new WaitForSeconds(0.1f); data = request.downloadHandler.data; if (data != null && data.Length > 0) { fs.Write(data, 0, data.Length); bytesDownloaded += data.Length; } progress = (float)bytesDownloaded / fileSize; if (bytesDownloaded >= fileSize) { isDownloading = false; Debug.Log("文件下载完成!"); yield break; } } } } void OnGUI() { GUI.HorizontalScrollbar(progressRect, 0, progress, 0, 1); } } ``` 在这个示例中,我们首先通过发送HEAD请求来获取文件大小,然后设置Range头字段来支持断点续传。我们使用了DownloadHandlerBuffer来下载文件,并使用FileStream来将下载的数据写入文件。我们还使用了一个协程来检查下载进度,并在GUI上显示进度条。如果下载完成,则停止显示进度条。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值