Unity3d StreamingAssets资源复制到沙盒(一)

由于项目已实现热更新,所以资源优先由沙盒读取,或完全直接从沙盒读取。为了防止在更新大版本时使用到旧项目的资源,所以需要对沙盒中旧的资源进行覆盖。

暂时实现了以下两种copy方案。

MD5文件格式与生成:

方法一:将本地资源一次性全部copy到沙盒,仅在首次安装或覆盖安装时对比oldfiles进行筛选覆盖

缺点:很慢。 30m资源耗时近20s,可优化:文件压缩后copy过去再解压。该方案暂时不用,仅做参考

private string oldfilesName = "oldfiles.txt";

private string filesName = "files.txt";

IEnumerator CopyFolder()

{

List<FileInfo> localInfos = new List<FileInfo>();

List<FileInfo> shaheInfos = new List<FileInfo>();

List<FileInfo> copyInfos = new List<FileInfo>();

//本地oldfiles

string src = getStreamingPath_for_www() + oldfilesName;

WWW www = new WWW(src);

yield return www;

if (!string.IsNullOrEmpty(www.error))

{

Debug.Log("www.error:" + www.error);

}

else

{

StringReader reader = new StringReader(www.text);

string line;

while ((line = reader.ReadLine()) != null)

{

string[] temp = line.Split(‘|‘);

string fileName = temp[0];

string md5 = temp[1];

int length = int.Parse(temp[2]);

FileInfo info;

info.fileName = fileName;

info.md5 = md5;

info.length = length;

localInfos.Add(info);

}

reader.Dispose();

reader.Close();

}

www.Dispose();

if (localInfos.Count > 0)

{

//沙盒oldfiles

string des = Application.persistentDataPath + "/" + oldfilesName;

if (File.Exists(des))

{

StreamReader reader = File.OpenText(des);

string line;

while ((line = reader.ReadLine()) != null)

{

string[] temp = line.Split(‘|‘);

string fileName = temp[0];

string md5 = temp[1];

int length = int.Parse(temp[2]);

FileInfo info;

info.fileName = fileName;

info.md5 = md5;

info.length = length;

shaheInfos.Add(info);

}

reader.Dispose();

reader.Close();

}

//需要更新oldfiles

copyInfos = CompareFileInfo(localInfos, shaheInfos);

foreach (var item in copyInfos)

{

//string  mfileName = item.fileName.Replace("\\","/");

string _src = getStreamingPath_for_www() + item.fileName;

string fileName = item.fileName.Substring(item.fileName.LastIndexOf(‘/‘) + 1);

string _des = Application.persistentDataPath + "/" + fileName;

//Debug.Log("des:" + _des);

//Debug.Log("src:" + _src);

WWW _www = new WWW(_src);

yield return _www;

if (!string.IsNullOrEmpty(_www.error))

{

Debug.Log("_www.error:" + _www.error);

}

else

{

FileStream stream = new FileStream(_des, FileMode.Create);

stream.Write(_www.bytes, 0, _www.bytes.Length);

stream.Flush();

stream.Close();

}

_www.Dispose();

}

if (copyInfos.Count > 0)

{

//copy oldfiles

StartCoroutine(copy(oldfilesName));

//删除 file 和 version

//删除这两个文件是copy完之后让游戏重新进行一次热更新,以保证沙盒资                  源与资源服资源保持一致(也是避免新资源被copy而报错)

string filepath = Application.persistentDataPath + "/files.txt";

string versionpath = Application.persistentDataPath + "/Version";

if (File.Exists(filepath))

{

File.Delete(filepath);

}

if (File.Exists(versionpath))

{

File.Delete(versionpath);

}

}

Debug.logger.Log("文件复制完成:共" + copyInfos.Count + "个文件");

}

else

{

Debug.logger.Log("本地无文件:" + copyInfos.Count + "个文件");

}

StartCoroutine(compareVersion());

}

/// <summary>

/// 将streaming path 下的文件copy到对应用

///

IEnumerator copy(string fileName)

{

string src = getStreamingPath_for_www() + fileName;

string des = Application.persistentDataPath + "/" + fileName;

//Debug.Log("des:" + des);

//Debug.Log("src:" + src);

WWW www = new WWW(src);

yield return www;

if (!string.IsNullOrEmpty(www.error))

{

Debug.Log("www.error:" + www.error);

}

else

{

if (File.Exists(des))

{

File.Delete(des);

}

FileStream fsDes = File.Create(des);

fsDes.Write(www.bytes, 0, www.bytes.Length);

fsDes.Flush();

fsDes.Close();

}

www.Dispose();

}

//比较md5

List<FileInfo> CompareFileInfo(List<FileInfo> localInfos, List<FileInfo> shaheInfos)

{

List<FileInfo> downloadList = new List<FileInfo>();

for (int i = 0; i < localInfos.Count; i++)

{

FileInfo info = localInfos[i];

bool flag = NeedCopy(info.fileName, info.md5, shaheInfos);

if (flag)

{

downloadList.Add(info);

}

}

return downloadList;

}

//true 需要下载,false 不用下载

bool NeedCopy(string fileName, string md5, List<FileInfo> shaheInfos)

{

for (int i = 0; i < shaheInfos.Count; i++)

{

if (shaheInfos[i].fileName == fileName)

{

if (shaheInfos[i].md5 == md5)

{

return false;

}

else

{

return true;

}

}

}

return true;

}

string getStreamingPath_for_www()

{

string pre = "file://";

#if UNITY_EDITOR

pre = "file://";

#elif UNITY_ANDROID

pre = "";

#elif UNITY_IPHONE

pre = "file://";

#endif

string path = pre + Application.streamingAssetsPath + "/";

return path;

}

string getPersistentPath_for_www()

{

string pre = "file://";

#if UNITY_EDITOR || UNITY_STANDALONE_WIN

pre = "file:///";

#elif UNITY_ANDROID

pre = "file://";

#elif UNITY_IPHONE

pre = "file://";

#endif

string path = pre + Application.persistentDataPath + "/";

return path;

}

#endregion

方法二、仅copy覆盖沙盒中存在的旧资源

时间: 2024-11-06 03:28:34

Unity3d StreamingAssets资源复制到沙盒(一)的相关文章

IOS沙盒(SandBox)机制以及沙盒目录路径的获取

IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容.所有的非代码文件都保存在这个地方,比如图片.声音.属性列表和文本文件等. (1).应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒. (2).应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里. (3).苹果禁止任何读.写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中. (

iOS沙盒(sandbox)机制及获取沙盒路径

一. 每个iOS应用SDK都被限制在“沙盒”中,“沙盒”相当于一个加了仅主人可见权限的文件夹,苹果对沙盒有以下几条限制. (1).应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒. (2).应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里. (3).苹果禁止任何读.写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中. (4).沙盒根目录里有三个文件夹:Documents,一般应该把应用程序的数据文件存到

iOS沙盒(sandbox)机制及获取沙盒路径

一.每个iOS应用SDK都被限制在沙盒中,沙盒相当于一个加了仅主人可见权限的文件夹,苹果对沙盒有以下几条限制. (1).应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒. (2).应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里. (3).苹果禁止任何读.写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中. (4).沙盒根目录里有三个文件夹: Documents:一般应该把应用程序的数据文件存到这个文件

ios - 沙盒和NSBundle

沙盒 1.沙盒机制介绍 iOS中的沙盒机制是一种安全体系.每个iOS程序都有一个独立的文件系统(存储空间),而且只能在对应的文件系统中进行操作,此区域被称为沙盒.应用必须待在自己的沙盒里,其他应用不能访问该沙盒.所有的非代码文件都要保存在此,例如属性文件plist.文本文件.图像.图标.媒体资源等.沙盒是用来存入缓冲区的,APP关掉,缓存被自动清理. 沙盒路径:NSLog(@"%@",NSHomeDirectory()); 2.沙盒目录结构 (1)/AppName.app 应用程序的程

游戏开发设计模式之子类沙盒模式(unity3d 示例实现)

积累提供所有操作(的实现)来定义子类的行为用一个最简单的例子来讲解这个模式玩家操纵的英雄也就是这个游戏的主角会有许多技能,我们想定义许多不同的技能,来让玩家使用.首 先我们定义一个skillBase类作为基类,我们所有技能的动作都在这里实现.我们可以从这些基本元动作中组合出各种各样的技能,甚至成百上千种,可以 设计一个doc文档来设计各种技能的操作,及操作顺序.这就是之所以为什么叫子类沙盒的原因,把实现技能的方法作为沙盒,向这个沙盒里加入各种各样的元动 作来组成各种各样的技能.以传说系列的凤凰天

IOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)模拟器应用沙盒的根路径在: (apple是用户名, 8.0是模拟器版本)/Users/apple/Libra

IOS SDK详解之沙盒(一)图解+小工具

原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 前言: IOS沙盒机制限制了App的访问权限,进而保护用户的数据信息. 一 查看沙盒结构 和一些百度来的博客显示隐藏稳文件的方式不同,本文也提供两种方式,简单粗暴. 方式一 使用工具simpholders(推荐) 下载链接 http://simpholders.com/ 效果如图 方式二 直接使用代码 用以下代码,log出documents/路径 NSURL * url = [[[NSFileManager defau

浅谈iOS沙盒目录

原文地址:http://blog.csdn.net/wzzvictory/article/details/18269713 出于安全考虑,iOS系统的沙盒机制规定每个应用都只能访问当前沙盒目录下面的文件(也有例外,比如系统通讯录能在用户授权的情况下被第三方应用访问),这个规则把iOS系统的封闭性展现的淋漓尽致. 一.沙盒中几个主要的目录 每个沙盒下面都有相似的目录结构,如下图所示(出自苹果官方文档): 每个应用的沙盒目录都是相似的,主要包含图中所示的4个目录: 1.MyApp.app ①存放内容

计算沙盒下文件夹内容大小 清空沙盒 文件 目录

1 +(float)fileSizeForDir:(NSString*)path//计算文件夹下文件的总大小 2 3 { 4 5 NSFileManager *fileManager = [[NSFileManager alloc] init]; 6 7 float size =0; 8 9 NSArray* array = [fileManager contentsOfDirectoryAtPath:path error:nil]; 10 11 for(int i = 0; i<[array