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