[游戏开发][Unity]Assetbundle下载篇(4)检查断点续传以及开始下载AB包

这篇具有很好参考价值的文章主要介绍了[游戏开发][Unity]Assetbundle下载篇(4)检查断点续传以及开始下载AB包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

打包与资源加载框架目录

正文

AB包之前,要检查该AB包是否下载中断过,例如用户杀程序,卡死等情况。

前文有讲解过,下载AB包会先下载到临时文件夹,全部下载成功后,全部剪切到persistentDataPath沙盒目录中。

回顾一下之前的筛选机制,哪些AB包可以加入下载列表,其中并没有临时下载目录的判断。

该AB包数据是否加入列表要经过下面几个筛选

  1. 判断persistentDataPath沙盒目录是否存在该AB包,如果存在证明之前下载过,无需加入下载列表。

  1. 判断StreamingAsset目录中是否存在该AB包,如果存在证明打包时该AB包已经在包体里,无需加入下载列表。

  1. 如果该AB包的下载类型是游戏内下载,或者叫边玩边下,那么不需要在游戏启动热更时下载,无需加入下载列表

检查是否在临时下载目录中是否存在的代码如下

private IEnumerator CheckTempFileComplete(List<PatchElement> list, bool isPostCheck)
{
    PatchEventDispatcher.SendCheckDownloadedFileMd5();
    var sw = new Stopwatch();
    sw.Start();
    var buf = new byte[10240];
    this.totalDownloadSizeKB = 0;
    this.currentDownloadSizeKB = 0;
    this.currentDownloadCount = 0;
    using (var md5 = System.Security.Cryptography.MD5.Create())
    {
        foreach (var ele in list)
        {
            this.totalDownloadSizeKB += ele.SizeKB;
            string savePath = AssetPathHelper.MakeDownloadTempPath(ele.Name);
            if (!File.Exists(savePath))
            {
                //下载后的检查需要抛出异常,下载前的检查跳过不存在文件
                if (isPostCheck)
                {
                    PatchHelper.Log(ELogLevel.Error, $"[checking md5] file is not existed: {ele.Name}");
                    failedOnCheckDownload = true;
                    yield break;
                }
                else
                {
                    continue;
                }
            }
            
            using (var fs = new FileStream(savePath, FileMode.Open, FileAccess.Read))
            {
                int byteRead;
                md5.Initialize();
                while ((byteRead = fs.Read(buf, 0, buf.Length)) > 0)
                {
                    md5.TransformBlock(buf, 0, byteRead, null, 0);
                    if (sw.ElapsedMilliseconds > 250)
                    {
                        yield return null;
                        sw.Restart();
                    }
                }
                md5.TransformFinalBlock(buf, 0, 0);
                fs.Close();
                string localMd5 = BitConverter.ToString(md5.Hash).Replace("-", "");
                if (string.Equals(ele.MD5, localMd5, StringComparison.OrdinalIgnoreCase))
                {
                    //MotionLog.Log(ELogLevel.Log, StringFormat.Format("skip download existed file: {0}", savePath));
                    ele.SkipDownload = true;
                    this.currentDownloadSizeKB += ele.SizeKB;
                    this.currentDownloadCount++;
                }
                else if (isPostCheck)
                {
                    PatchHelper.Log(ELogLevel.Error, $"Web file md5 verification error : {ele.Name}");
                    PatchHelper.Log(ELogLevel.Error, $"local md5 is : {localMd5}");
                    PatchHelper.Log(ELogLevel.Error, $"md5 in manifest is : {ele.MD5}");
                    PatchEventDispatcher.SendWebFileMD5VerifyFailedMsg(ele.Name);
                    failedOnCheckDownload = true;
                    File.Delete(savePath);
                    yield break;
                }
            }
        }
    }
}

布尔值isPostCheck的作用是是否是二次检测,先不管它

按流程来走

  1. 检查该AB包是否在临时文件夹中存在,如果不存在则跳过

  1. 如果已存在,创建该临时下载文件的MD5,与下载清单中的MD5做对比

  1. 如果MD5对比一致,则标记该AB包数据为SkipDownload,同时标记下载数据长度,供UI显示

我们项目里目前的代码被人改了,我也有有点看不懂为何要用 md5.TransformBlock的方式

下面是一套生成MD5码的代码,加载文件,MD5CryptoServiceProvider会根据加载的stream生成hash,

readonly MD5CryptoServiceProvider _provider = new MD5CryptoServiceProvider();
public static string StreamMD5()
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        byte[] hashBytes = _provider.ComputeHash(stream);
        return ToString(hashBytes);
    }
}
private static string ToString(byte[] hashBytes)
{
    var sb = new StringBuilder();
    foreach (var t in hashBytes)
    sb.Append(t.ToString("x2"));
    return sb.ToString();
}

首先要判断临时下载目录中是否存在该文件,如果没有,我们项目文章来源地址https://www.toymoban.com/news/detail-490922.html

private IEnumerator Download()
{
    // 计算下载文件的总大小
    totalDownloadCount = _patcher.DownloadList.Count;
    if (totalDownloadCount == 0)
    {
        _patcher.SwitchNext();
        yield break;
    }
    //先检查一遍temp目录有没有下载完的, 计算这次实际需要下载的个数和size
    yield return CheckTempFileComplete(_patcher.DownloadList, false);

    // 开始下载列表里的所有资源
    PatchHelper.Log(ELogLevel.Log, $"Begine download web files : {totalDownloadCount-currentDownloadCount}");
    PatchEventDispatcher.SendPatchStatesChangeMsg(EPatchStates.DownloadWebFiles);
    var startTime = Time.realtimeSinceStartup;
    var newDownloaded = new List<PatchElement>(_patcher.DownloadList.Count);
    foreach (var element in _patcher.DownloadList)
    {
        if (element.SkipDownload) continue;
        newDownloaded.Add(element);
    }

    if (useMultiRequest)
    {
        yield return DownloadWithMultiTask(newDownloaded);
    }
    else
    {
        yield return DownloadWithSingleTask(newDownloaded);
    }
    if (failedOnDownload)
    {
        yield break;
    }
    MotionLog.Log(ELogLevel.Log, $"<color=#ff0000>Downloading {newDownloaded.Count} files cost {Time.realtimeSinceStartup-startTime} sec.</color>");
    //全部下载完成后把这次新下载的文件再校验一遍,如果有文件失败就退出
    yield return CheckTempFileComplete(newDownloaded, true);
    if (failedOnCheckDownload)
    {
        yield break;
    }
    
    if (_patcher.MiniAndroid)
    {
        var fileCount = _patcher.DownloadList[0].Version; // tricky storing filecount in field [version]
        var zipFileName = _patcher.DownloadList[0].Name;
        yield return DecompressInitPack(zipFileName, fileCount);
    }
    else
    {
        yield return DeployDownloadFiles();
    }

    // 最后清空下载列表
    _patcher.DownloadList.Clear();
    _patcher.SwitchNext();
}

到了这里,关于[游戏开发][Unity]Assetbundle下载篇(4)检查断点续传以及开始下载AB包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [游戏开发][Unity]Assetbundle打包篇(1)打包流程介绍

    打包与资源加载框架目录 先捋一下打AB包的整体思路,首先,Unity4.6版本之后就使用了全新的打包接口 无论是全新打包还是增量打包都是使用这个API,所以一切的一切,都要围绕这个API开始讲起。 该API有四个参数 string outputPath AssetBundleBuild[] builds BuildAssetBundleOptions assetBundle

    2024年02月10日
    浏览(36)
  • [游戏开发][Unity]Assetbundle打包篇(2)打包资源配置篇

    打包与资源加载框架目录 可视化配置的方式有很多种,Json、XML、以及Unity内置的ScriptableObject序列化 配置文件里要有哪些内容呢,很显然,最重要的就是目标文件路径,其次是权重类型,权重类型有:必要打包型、被引用打包型、忽略类型。为何会有忽略类型呢,是因为我们

    2024年02月09日
    浏览(39)
  • lazarus、delphi文件Http下载断点续传的实现

    下载大文件时,断点续传是很有必要的,特别是网速度慢且不稳定的情况下,很难保证不出意外,一旦意外中断,又要从头下载,会很让人抓狂。断点续传就能很好解决意外中断情况,再次下载时不需要从头下载,从上次中断处继续下载即可,这样下载几G或十几G大小的一个

    2024年02月13日
    浏览(51)
  • [游戏开发][Unity]Assetbundle打包篇(5)使用Manifest二次构建资源索引

    打包与资源加载框架目录 正文开始前,先把打包代码放过来,请注意,前面的代码已省略,自己去对比前面的文章。本篇文章从第一次执行打包代码开始。 第一次调用BuildPipeline.BuildAssetBundles打包API后(详见代码第七行),会返回AssetBundleManifest的引用, 【疑问】: BuildPipe

    2024年02月03日
    浏览(34)
  • 断点续传下载引出的http header的range和content-range参数

    最近同事在做安卓的断点续传下载,然后遇到了在请求头添加RANGE参数设置时: 网络上找的资料都是设置contentLength,同时测试后,发现中间下载无法返回206成功,最终发现是需要end参数-1.此处稍微记录一下,主要了解一下相关的知识。 HTTP1.1 协议(RFC2616)开始支持获取文件的

    2024年02月10日
    浏览(65)
  • 断点续传下载:深入理解 HTTP Header 中的 Range 和 Content-Range 参数

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bAhEY9hc-1687309020087)(https://example.com/resume-download-image)] 在进行文件下载时,我们经常会遇到网络不稳定或其他中断情况。为了提供更好的用户体验和节省带宽资源,断点续传技术应运而生。HTTP 协议通过

    2024年02月10日
    浏览(52)
  • Spring Boot实现HTTP大文件断点续传分片下载-大视频分段渐进式播放

    服务端如何将一个大视频文件做切分,分段响应给客户端,让浏览器可以渐进式地播放。 Spring Boot实现HTTP分片下载断点续传,从而实现H5页面的大视频播放问题,实现渐进式播放,每次只播放需要播放的内容就可以了,不需要加载整个文件到内存中。 文件的断点续传、文件多

    2024年02月14日
    浏览(69)
  • U3D客户端框架之支持断点续传的文件下载器实现方案

            文件下载器是应用程序的基础模块,为应用程序与外部网络交互提供了必要的桥梁。该模块设计初衷是为了热更新过程中,下载CDN站点上的文件资源,所以下载器会验证 要下载的文件是否存在于CDN中。如果存在允许下载器继续工作;如果不存在会跳过本地下载。

    2024年02月07日
    浏览(52)
  • 旧版Xcode文件较大导致下载总是失败但又不能断点续传重新开始的解决方法

    旧版mac下载旧版Xcode时需要进入https://developer.apple.com/download/all/?q=xcode下载,但是下载这些文件需要登录。登录后下载中途很容易失败,失败后又必须重新下载。 下载这里面的内容都需要登录,经过分析需提供其cookie,我这里使用的是motrix。需要下载时先通过搜索找到你要下载

    2024年02月15日
    浏览(67)
  • Spring-Boot实现HTTP大文件断点续传分片下载-大视频分段渐进式播放

    服务端如何将一个大视频文件做切分,分段响应给客户端,让浏览器可以渐进式地播放。 Spring Boot实现HTTP分片下载断点续传,从而实现H5页面的大视频播放问题,实现渐进式播放,每次只播放需要播放的内容就可以了,不需要加载整个文件到内存中。 文件的断点续传、文件多

    2024年02月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包