7.下载资源对比文件

7.下载相关-下载资源对比文件


7.1 知识点

把基础框架丢进来,创建AB包更新管理器,继承基于MonoBehaviour的单例

// AB包更新管理器
public class AssetBundleUpdateManager : BaseSingletonInMonoBehaviour<AssetBundleUpdateManager>
{
}

AB包更新管理器定义下载文件的方法

private void DownLoadFile(string fileName, string localPath)
{
    try
    {
        // 创建一个FTP连接 用于下载
        FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/AB/PC/" + fileName)) as FtpWebRequest;

        // 设置一个通信凭证 这样才能下载(如果有匿名账号 可以不设置凭证 但是实际开发中 建议 还是不要设置匿名账号)
        NetworkCredential networkCredential = new NetworkCredential("MrTao", "MrTao");
        ftpWebRequest.Credentials = networkCredential;

        // 其它设置
        // 设置代理为null
        ftpWebRequest.Proxy = null;
        // 请求完毕后 是否关闭控制连接
        ftpWebRequest.KeepAlive = false;
        // 操作命令-下载
        ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
        // 指定传输的类型 2进制
        ftpWebRequest.UseBinary = true;

        // 下载文件
        // ftp的流对象
        FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
        Stream downLoadStream = ftpWebResponse.GetResponseStream();
        using (FileStream fileStream = File.Create(localPath))
        {
            // 一点一点的下载内容
            byte[] bytes = new byte[2048];

            // 返回值 代表读取了多少个字节
            int contentLength = downLoadStream.Read(bytes, 0, bytes.Length);

            // 循环下载数据
            while (contentLength != 0)
            {
                // 写入到本地文件流中
                fileStream.Write(bytes, 0, contentLength);
                // 写完再读
                contentLength = downLoadStream.Read(bytes, 0, bytes.Length);
            }

            // 循环完毕后 证明下载结束
            fileStream.Close();
            downLoadStream.Close();

            print(fileName + "下载成功");
        }
    }
    catch (Exception ex)
    {
        print(fileName + "下载失败" + ex.Message);
    }
}

创建AB包信息类 AssetBundleInfo,包括名字,大小和md5码。运算符重载比较md5码。

public class AssetBundleInfo : MonoBehaviour
{
    public string assetBundleName; // AB包名字
    public long size;              // AB包大小
    public string md5;             // AB包md5码

    public AssetBundleInfo(string assetBundleName, string size, string md5)
    {
        this.assetBundleName = assetBundleName;
        this.size = long.Parse(size);
        this.md5 = md5;
    }

    // 重载==运算符,用于比较两个 AssetBundleInfo 对象的 md5 字段是否相等
    public static bool operator ==(AssetBundleInfo a, AssetBundleInfo b)
    {
        // 如果两个对象都为null,或者两者的md5字段相等,则认为它们相等
        return (ReferenceEquals(a, null) && ReferenceEquals(b, null)) ||
               (!ReferenceEquals(a, null) && !ReferenceEquals(b, null) && a.md5 == b.md5);
    }

    // 重载!=运算符,用于比较两个 AssetBundleInfo 对象的 md5 字段是否不相等
    public static bool operator !=(AssetBundleInfo a, AssetBundleInfo b)
    {
        // 如果两个对象中有一个为null,或者两者的md5字段不相等,则认为它们不相等
        return !(a == b);
    }

    // 重写Equals方法,用于比较两个 AssetBundleInfo 对象是否相等
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        AssetBundleInfo other = (AssetBundleInfo)obj;
        return this.md5 == other.md5;
    }

    // 重写GetHashCode方法,用于生成哈希码
    public override int GetHashCode()
    {
        return md5.GetHashCode();
    }
}

AB包更新管理器定义存储远端AB包信息的字典和下载AB资源对比文件的方法,从服务器下载AB资源对比文件并对齐内容进行字符串切割保存到AB包信息的字典中。

// 用于存储远端AB包信息的字典 之后 和本地进行对比即可完成 更新 下载相关逻辑
private Dictionary<string, AssetBundleInfo> remoteAssetBundleInfoDictionary = new Dictionary<string, AssetBundleInfo>();

public void DownLoadABCompareFile()
{
    // 从资源服务器下载资源对比文件
    // www UnityWebRequest ftp相关api
    print(Application.persistentDataPath);
    DownLoadFile("ABCompareInfo.txt", Application.persistentDataPath + "/ABCompareInfo.txt");

    // 获取资源对比文件中的 字符串信息 进行拆分
    string info = File.ReadAllText(Application.persistentDataPath + "/ABCompareInfo.txt");
    string[] strs = info.Split('|');//通过|拆分字符串 把一个个AB包信息拆分出来
    string[] infos = null;
    for (int i = 0; i < strs.Length; i++)
    {
        infos = strs[i].Split(' ');//又把一个AB的详细信息拆分出来
        // 记录每一个远端AB包的信息 之后 好用来对比
        remoteAssetBundleInfoDictionary.Add(infos[0], new AssetBundleInfo(infos[0], infos[1], infos[2]));
    }

    print("远端AB包对比文件 加载结束");
}

7.2 知识点代码

AssetBundleInfo

using UnityEngine;

public class AssetBundleInfo : MonoBehaviour
{
    public string assetBundleName; // AB包名字
    public long size;              // AB包大小
    public string md5;             // AB包md5码

    public AssetBundleInfo(string assetBundleName, string size, string md5)
    {
        this.assetBundleName = assetBundleName;
        this.size = long.Parse(size);
        this.md5 = md5;
    }

    // 重载==运算符,用于比较两个 AssetBundleInfo 对象的 md5 字段是否相等
    public static bool operator ==(AssetBundleInfo a, AssetBundleInfo b)
    {
        // 如果两个对象都为null,或者两者的md5字段相等,则认为它们相等
        return (ReferenceEquals(a, null) && ReferenceEquals(b, null)) ||
                (!ReferenceEquals(a, null) && !ReferenceEquals(b, null) && a.md5 == b.md5);
    }

    // 重载!=运算符,用于比较两个 AssetBundleInfo 对象的 md5 字段是否不相等
    public static bool operator !=(AssetBundleInfo a, AssetBundleInfo b)
    {
        // 如果两个对象中有一个为null,或者两者的md5字段不相等,则认为它们不相等
        return !(a == b);
    }

    // 重写Equals方法,用于比较两个 AssetBundleInfo 对象是否相等
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }

        AssetBundleInfo other = (AssetBundleInfo)obj;
        return this.md5 == other.md5;
    }

    // 重写GetHashCode方法,用于生成哈希码
    public override int GetHashCode()
    {
        return md5.GetHashCode();
    }
}

AssetBundleUpdateManager

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using UnityEngine;
using static ABUpdateMgr;

//AB包更新管理器
public class AssetBundleUpdateManager : BaseSingletonInMonoBehaviour<AssetBundleUpdateManager>
{
    //用于存储远端AB包信息的字典 之后 和本地进行对比即可完成 更新 下载相关逻辑
    private Dictionary<string, AssetBundleInfo> remoteAssetBundleInfoDictionary = new Dictionary<string, AssetBundleInfo>();

    public void DownLoadABCompareFile()
    {
        //1.从资源服务器下载资源对比文件
        // www UnityWebRequest ftp相关api
        print(Application.persistentDataPath);
        DownLoadFile("ABCompareInfo.txt", Application.persistentDataPath + "/ABCompareInfo.txt");

        //2.就是获取资源对比文件中的 字符串信息 进行拆分
        string info = File.ReadAllText(Application.persistentDataPath + "/ABCompareInfo.txt");
        string[] strs = info.Split('|');//通过|拆分字符串 把一个个AB包信息拆分出来
        string[] infos = null;
        for (int i = 0; i < strs.Length; i++)
        {
            infos = strs[i].Split(' ');//又把一个AB的详细信息拆分出来
            //记录每一个远端AB包的信息 之后 好用来对比
            remoteAssetBundleInfoDictionary.Add(infos[0], new AssetBundleInfo(infos[0], infos[1], infos[2]));
        }

        print("远端AB包对比文件 加载结束");
    }

    private void DownLoadFile(string fileName, string localPath)
    {
        try
        {
            //1.创建一个FTP连接 用于下载
            FtpWebRequest ftpWebRequest = FtpWebRequest.Create(new Uri("ftp://127.0.0.1/AB/PC/" + fileName)) as FtpWebRequest;

            //2.设置一个通信凭证 这样才能下载(如果有匿名账号 可以不设置凭证 但是实际开发中 建议 还是不要设置匿名账号)
            NetworkCredential networkCredential = new NetworkCredential("MrTao", "MrTao");
            ftpWebRequest.Credentials = networkCredential;

            //3.其它设置
            //  设置代理为null
            ftpWebRequest.Proxy = null;
            //  请求完毕后 是否关闭控制连接
            ftpWebRequest.KeepAlive = false;
            //  操作命令-下载
            ftpWebRequest.Method = WebRequestMethods.Ftp.DownloadFile;
            //  指定传输的类型 2进制
            ftpWebRequest.UseBinary = true;

            //4.下载文件
            //  ftp的流对象
            FtpWebResponse ftpWebResponse = ftpWebRequest.GetResponse() as FtpWebResponse;
            Stream downLoadStream = ftpWebResponse.GetResponseStream();
            using (FileStream fileStream = File.Create(localPath))
            {
                //一点一点的下载内容
                byte[] bytes = new byte[2048];

                //返回值 代表读取了多少个字节
                int contentLength = downLoadStream.Read(bytes, 0, bytes.Length);

                //循环下载数据
                while (contentLength != 0)
                {
                    //写入到本地文件流中
                    fileStream.Write(bytes, 0, contentLength);
                    //写完再读
                    contentLength = downLoadStream.Read(bytes, 0, bytes.Length);
                }

                //循环完毕后 证明下载结束
                fileStream.Close();
                downLoadStream.Close();

                print(fileName + "下载成功");
            }
        }
        catch (Exception ex)
        {
            print(fileName + "下载失败" + ex.Message);
        }

    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏