Unity C# 断点续存
**前言:**看了很多断点续存的博客,几乎用的都是UnityWebRequest。我用的chfs服务器工具,在UnityWebRequest.head请求头时报错404。但这位作者用的HttpWebRequest,可以放心食用。
作者地址
**补充:**上次网上抄的码,自己用chfs服务器工具测试没问题;然后在实际开发的项目中,换了地址会卡死,于是又改用UnityWebRequest,又就可以用了,码贴在了最后。如果这篇文章荣幸的被大佬看到,跪求大佬指点一二,非常感谢😀😀😀
**思考:**无论是哪种api方法,思路都是一样的。
1,获得资源的字节总长度,
2,获得本地资源已下载的字节长度
3,请求网络从”本地资源已下载的字节长度“开始进行下载
使用HttpWebRequest
using System.Collections;
using System.IO;
using System.Net;
using UnityEngine;
public class DownloadVideo : MonoBehaviour
{
string url = "http://192.168.1.253/chfs/shared/VideoTest.mp4";
string savePath = "Android/Qi/Video/VideoTest.mp4";
private void Start()
{
StartCoroutine(DownLoad(url, savePath));
}
/// <summary>
/// 断点续存
/// </summary>
IEnumerator DownLoad(string uri, string saveFile)
{
//打开网络连接
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
HttpWebRequest requestGetCount = (HttpWebRequest)WebRequest.Create(uri);
long countLength = requestGetCount.GetResponse().ContentLength;
//打开上次下载的文件或新建文件
long lStartPos = 0;
FileStream fs;
if (File.Exists(saveFile))
{
fs = File.OpenWrite(saveFile);
lStartPos = fs.Length;
if (countLength - lStartPos <= 0)
{
fs.Close();
yield break;
}
fs.Seek(lStartPos, SeekOrigin.Current); //移动文件流中的当前指针
}
else
{
fs = new FileStream(saveFile, FileMode.Create);
}
if (lStartPos > 0)
{
request.AddRange((int)lStartPos); //设置Range值
print(lStartPos);
}
//向server请求。获得server回应数据流
Stream ns = request.GetResponse().GetResponseStream();
int len = 1024 * 8;
byte[] nbytes = new byte[len];
int nReadSize = 0;
nReadSize = ns.Read(nbytes, 0, len);
while (nReadSize > 0)
{
fs.Write(nbytes, 0, nReadSize);
nReadSize = ns.Read(nbytes, 0, len);
//Debug.Log($"已经下载:{fs.Length / 1024} kb/{countLength / 1024} kb----{((double)fs.Length / countLength*100).ToString("0.00")}%");
yield return false;
}
ns.Close();
fs.Close();
//这里放更新安装代码,或者能够測试这个下载的包有没有出错,验证sha和md5
}
}
使用UnityWebRequest
IEnumerator RenewDownLoad(string fullUrl, string fullSavePath)
{
long countLength;
using (UnityWebRequest uwrGetCount = UnityWebRequest.Head(fullUrl))
{
yield return uwrGetCount.SendWebRequest();
//获取资源字节长度
countLength = long.Parse(uwrGetCount.GetResponseHeader("Content-Length"));
Debug.Log(countLength);
}
using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(fullUrl))
{
//append设置为true文件写入方式为接续写入,不覆盖原文件。
unityWebRequest.downloadHandler = new DownloadHandlerFile(fullSavePath, true);
//创建文件
FileInfo file = new FileInfo(fullSavePath);
//当前下载的文件长度
long fileLength = file.Length;
//请求网络数据从第fileLength到最后的字节
unityWebRequest.SetRequestHeader("Range", $"bytes={fileLength}-");//设置Range值
if (fileLength < countLength)
{
unityWebRequest.SendWebRequest();
while (!unityWebRequest.isDone)
{
double lastProgress = (double)fileLength / countLength;//上次下载的进度
Debug.Log($"{fullSavePath}上次下载:{(lastProgress * 100).ToString("0.00")}% ");
double newProgress = unityWebRequest.downloadProgress;
double currProgress = lastProgress + newProgress * (1 - lastProgress);
Debug.Log($"{fullSavePath}已经下载:{(currProgress * 100).ToString("0.00")}% ");
yield return null;
}
}
if (unityWebRequest.isDone)
{
Debug.Log($"{fullSavePath}已经下载:100%");
}
}
}