这个是模拟客户端更新资源的代码:
using System.Collections;
using System.Collections.Generic;using System.IO;
using System.Text;
using UnityEngine;
/// <summary>
/// 资源跟新逻辑
/// </summary>
public class ResUpdate02 : MonoBehaviour
{
#region 基本信息
private string LocalPath; //本地资源路径
private string ServerPath; //服务器资源路径(伪服务器)
private string ConfigurePathName; //资源配置信息
private Dictionary<string, string> LocalDic; //本地资源配置信息
private Dictionary<string, string> ServerDic; //服务器资源配置信息
private List<string> NeedUpadteAsstesPathName; //需要跟新的资源
private bool isConfigureUpadate; //本地资源配置信息是否需要跟新
#endregion
/// <summary>
/// 初始化配置信息
/// </summary>
private void Awake()
{
LocalPath = Application.streamingAssetsPath + "/";
ServerPath = "http://localhost/StreamingAssets/";
ConfigurePathName = "Configure.txt";
LocalDic = new Dictionary<string, string>();
ServerDic = new Dictionary<string, string>();
NeedUpadteAsstesPathName = new List<string>();
isConfigureUpadate = false;
}
/// <summary>
/// 跟新资源
/// </summary>
private void Start()
{
//加载本地配置信息
StartCoroutine(Download(LocalPath + ConfigurePathName, delegate (WWW LocalPathwww)
{
SaveConfigure(LocalPathwww.text, LocalDic); //保存本地配置信息
//加载服务器配置信息
StartCoroutine(Download(ServerPath + ConfigurePathName, delegate (WWW ServerPathwww)
{
SaveConfigure(ServerPathwww.text, ServerDic); //保存服务器配置信息
CalculationUpdateInfo(); //计算需要更新的信息
UpdateAssets(); //更新资源
}));
}));
}
/// <summary>
/// 更新资源
/// </summary>
private void UpdateAssets()
{
if (NeedUpadteAsstesPathName.Count == 0) //说明资源更新完了
{
UpdateCalculationMessage(); //更新配置信息
return; //任务完成跳出
}
string tempPath = NeedUpadteAsstesPathName[0];//获取需要跟新的资源路径
NeedUpadteAsstesPathName.RemoveAt(0); //第一个需要更新的资源路径已经获取到就移除以防重复跟新
//加载资源并且跟新
StartCoroutine(Download(ServerPath + tempPath, delegate (WWW www)
{
ReplaceAssets(LocalPath + tempPath, www.bytes); //跟新资源
UpdateAssets(); //加载需要跟新的下一个资源
}));
}
/// <summary>
/// 替换资源
/// </summary>
/// <param name="path"></param>
/// <param name="Asstesbytes"></param>
private void ReplaceAssets(string path, byte[] Asstesbytes)
{
FileStream fileStream = new FileStream(path, FileMode.Create); //打开文件流(有该文件夹覆盖没有就创建)
fileStream.Write(Asstesbytes, 0, Asstesbytes.Length); //把资源信息存储到本地文件
fileStream.Flush(); //把缓冲区的文件也读取到本地
fileStream.Close(); //关闭流
fileStream.Dispose(); //释放流
}
/// <summary>
/// 跟新配置信息
/// </summary>
private void UpdateCalculationMessage()
{
StringBuilder sb = new StringBuilder();
foreach (string key in ServerDic.Keys)
{
sb.Append(key).Append(":").Append(ServerDic[key] + "\n"); //存储配置信息
}
#region 写入方法一
//FileStream fileStream = new FileStream(LocalPath + ConfigurePathName, FileMode.Create); //开启存储流
//byte[] messageArray = Encoding.UTF8.GetBytes(sb.ToString()); //字符转换字节数组
//fileStream.Write(messageArray, 0, messageArray.Length); //写入本地
//fileStream.Flush(); //清除缓存
//fileStream.Close(); //关闭流
//fileStream.Dispose(); //释放占用资源
#endregion
#region 写入方法二
using (FileStream fileStream = new FileStream(LocalPath + ConfigurePathName, FileMode.Create))
{
byte[] messageArray = Encoding.UTF8.GetBytes(sb.ToString());
fileStream.Write(messageArray, 0, messageArray.Length);
fileStream.Flush();
}
#endregion
}
/// <summary>
/// 保存配置信息
/// </summary>
/// <param name="configureMessage">配置信息</param>
/// <param name="dic">要保持到那个容器</param>
private void SaveConfigure(string configureMessage, Dictionary<string, string> dic)
{
if (configureMessage.Length == 0 || configureMessage == null)
{
return; //没有获取到信息直接跳出不执行
}
string[] tempArray = configureMessage.Split('\n'); //根据换行符分割字符
for (int i = 0; i < tempArray.Length; i++)
{
string[] temp = tempArray[i].Split(':'); //根据:分割字符串
if (temp != null && temp.Length == 2) //安全校验
{
dic.Add(temp[0], temp[1]); //存储信息
}
}
}
/// <summary>
///计算跟新信息
/// </summary>
private void CalculationUpdateInfo()
{
foreach (string key in ServerDic.Keys)
{
string tempKey = key;
if (LocalDic.ContainsKey(key) == false) //本地没有这个资源信息
{
NeedUpadteAsstesPathName.Add(key); //存储需要添加的信息
}
else //本地有这个资源信息
{
if (LocalDic[key] != ServerDic[key])
{
NeedUpadteAsstesPathName.Add(key); //存储需要跟新的信息
}
}
}
isConfigureUpadate = NeedUpadteAsstesPathName.Count > 0; //需要跟新配置信息
}
/// <summary>
/// 下载资源
/// </summary>
/// <param name="url">路径</param>
/// <param name="handle">下载信息的回调</param>
/// <returns></returns>
IEnumerator Download(string url, HandleFinishDownload handle)
{
WWW www = new WWW(url); //打开下载路径
yield return www; //等待下载完成
if (handle != null) //回调不为空
{
handle(www); //传递下载信息
}
www.Dispose(); //释放资源
}
public delegate void HandleFinishDownload(WWW www); //下载回调
}