最近要使用安卓更新下载apk更新功能,由于安卓机运行内存有限,下载大文件就得采用实时下载写入,实时释放内存的方法。考虑到网络环境不稳定时下载被迫中断的情况,重新从头下载会导致不必要的资源浪费,断点续传也很有必要。UnityWebRequest的DownloadHandlerFile可以做到实时下载写入,不必占用整个文件大小的内存。在unity新版本中,DownloadHandlerFile新增的append参数设置为true时文件写入方式为接续写入,不覆盖原文件。首先要获取服务器将要下载文件的大小这时可用UnityWebRequest.Head再通过GetResponseHeader("Content-Length")获取文件大小。需要注意的是如果服务器文件会有变动,可以自己加入数据校验,校验通过再续传文件。还有确保下载的文件URL是可以直接下载文件而不是重定向的url.
IEnumerator 断点下载(string 下载地址, string 保存路径)
{
Debug.Log("下载地址:" + 下载地址 + ",保存路径:" + 保存路径);
UnityWebRequest headRequest = UnityWebRequest.Head(下载地址);
yield return headRequest.SendWebRequest();
if (!string.IsNullOrEmpty(headRequest.error))
{
Debug.LogError("获取下载的文件大小失败");
yield break;
}
ulong totalLength = ulong.Parse(headRequest.GetResponseHeader("Content-Length"));//获取文件总大小
Debug.Log("获取大小"+ totalLength);
headRequest.Dispose();
UnityWebRequest Request = UnityWebRequest.Get(下载地址);
Request.downloadHandler = new DownloadHandlerFile(保存路径, true);//append设置为true文件写入方式为接续写入,不覆盖原文件。
FileInfo file = new FileInfo(保存路径);
ulong fileLength = (ulong)file.Length;
Debug.Log("文件总共大小:" + fileLength + ",totalLength=" + totalLength);
///request.SetRequestHeader("Range", "bytes=" + fileLength + "-"+ totalLength);
//设置文件从什么位置开始下载和写入
Request.SetRequestHeader("Range", "bytes=" + fileLength + "-");
if (fileLength < totalLength)
{
Request.SendWebRequest();
while (!Request.isDone)
{
double progress = (Request.downloadedBytes + fileLength) / (double)totalLength;
//进度条.value = (float)progress;
Debug.Log("下载进度" + progress);
yield return null;
}
}
if (string.IsNullOrEmpty(Request.error))
{
Debug.Log("下载成功"+ 保存路径);
}
else
{
Debug.LogError("下载失败"+ Request.error);
}
Request.Dispose();
}
?demo下载:https://download.csdn.net/download/chunyu90225/20061376
|