unity 断点续传

该博客介绍了如何利用HTTP协议的Accept-Ranges特性实现客户端的断点续传功能,通过设置请求特定字节区域来分段下载文件,并在下载过程中记录已下载长度,以便下次从断点继续下载。示例代码展示了Unity中使用C#进行断点续传的实现过程。
摘要由CSDN通过智能技术生成

需求:当前需求是 需要客户端更新 ab 包的时候可以断点续传

原理:原理就是请求特定的 字节区域,比如:下载一个文件,第一次请求区域为0-10M的字节,第二次为10M-20M,这个区域跨度自己设置就行。当你第三次没下载完关闭app,再次下载的时候,只需要读取你没下载完成的文件(边下载变存本地的文件)字节长度,从这个长度开始请求下载就可以了

使用:用的是http协议下载,HTTP 方面,Apache 或 Ngnix 默认都是支持 Accept-Ranges 的,别的服务器需要你自己去处理。

核心代码:

        string _url = "";
        Dictionary<string, string> httpHead = new Dictionary<string, string>();
        httpHead.Add("Range", "bytes=" + 请求其实位置+ "-" + 请求结束位置);
        WWW m_iWWW = new WWW(_url, null, httpHead);

实例:

    void Start() {
        StartCoroutine(RunWithContinue());
    }

    private WWW m_iWWW = null;
    private const int CHUNK_SIZE = 10 * 1024 * 1024;  //断点续传时,每次请求10M
    private long m_nChunk = 0;               //在分段下载中,记录当前下载段的长度
    private long m_nContinueDownloaded = 0;  //在分段下载中,记录当前下载文件已下载长度
    private IEnumerator RunWithContinue()
    {
        int nStartPos = 0;
        long nFileTotalLength = 102627178;

        System.IO.FileStream fsTmpFile = System.IO.File.Create(@"E:\UnitySpace\Test\Assets\abc.zip");

        while (nFileTotalLength > nStartPos)
        {
            string _url = "";

            Dictionary<string, string> httpHead = new Dictionary<string, string>();
            httpHead.Add("Range", "bytes=" + nStartPos.ToString() + "-" + (nStartPos + CHUNK_SIZE).ToString());

            m_iWWW = new WWW(_url, null, httpHead);
            yield return StartCoroutine(WaitForWWWWithTimeOut(m_iWWW, 10)); // 替换成带超时的版本 [3/11/2014 yao]

            if (!m_iWWW.isDone || (m_iWWW.error != null && m_iWWW.error.Length > 0))
            {
                Debug.Log("nStartPos:" + nStartPos + " CHUNK_SIZE:" + CHUNK_SIZE + " total:" + (nStartPos + CHUNK_SIZE));
                Debug.LogError("error======" + m_iWWW.error);
            }

            try
            {
                fsTmpFile.Write(m_iWWW.bytes, 0, m_iWWW.bytes.Length);
            }
            catch (System.Exception ex)
            {
                Debug.LogError("Exception======");
                break;
            }

            nStartPos += m_iWWW.bytes.Length;
            m_nContinueDownloaded = nStartPos;
            m_iWWW.Dispose();
            m_iWWW = null;
        }

        fsTmpFile.Close();
        fsTmpFile = null;
        Debug.LogError("结束");
    }

    private IEnumerator WaitForWWWWithTimeOut(WWW iWWW, float fTimeOut)
    {
        float fWait = 0;
        float fProgress = 0;
        do
        {
            //判断是否完成并等待
            if (iWWW.isDone)
            {
                yield break;
            }
            yield return new WaitForSeconds(0.1f);

            //累计超时时间
            fWait += 0.1f;
            if (fWait > fTimeOut)
            {
                yield break;
            }

            //如果进度走动了,则重新判断超时时间
            if (m_iWWW.progress > fProgress)
            {
                fProgress = m_iWWW.progress;
                fWait = 0;
            }
        } while (true);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值