Unity3D各平台Application.xxxPath的路径
前几天我们游戏在一个同事的Android手机上启动时无法正常进入,经查发现Application.temporaryCachePath和Application.persistentDataPath返回空字符串。便花时间认真研究了一下Unity3D的路径问题。我们常用的是以下四个路径:
Application.dataPath
Application.streamingAssetsPath
Application.persistentDataPath
Application.temporaryCachePath
根据测试,详细情况如下:
iOS:
Application.dataPath /var/containers/Bundle/Application/app sandbox/xxx.app/Data
Application.streamingAssetsPath /var/containers/Bundle/Application/app sandbox/test.app/Data/Raw
Application.temporaryCachePath /var/mobile/Containers/Data/Application/app sandbox/Library/Caches
Application.persistentDataPath /var/mobile/Containers/Data/Application/app sandbox/Documents
iOS和Mac OS X不同于Windows,app都是在一个沙盒空间中运行,每个app也有一个独立的数据存储空间,各app彼此不能互相访问、打扰。
dataPath是app程序包安装路径,app本身就在这里,此目录是只读的。streamingAssetsPath是dataPath下的Raw目录。
app的独立数据存储目录下有三个文件夹:Documents,Library和tmp。
Documents目录,这个目录用于存储需要长期保存的数据,比如我们的热更新内容就写在这里,iCloud会自动备份此目录。
Library目录,这个目录下有两个子目录,Caches和Preferences。
Caches是一个相对临时的目录,适合存放下载缓存的临时文件,空间不足时可能会被系统清除,Application.temporaryCachePath返回的就是此路径。我把热更新的临时文件写在这里,等一个版本的所有内容更新完全后,再把内容转移到Documents目录。
Preferences用于应用存储偏好设置,用NSUserDefaults读取或设置。
tmp目录,临时目录,存放应用运行时临时使用的数据。
需要注意的是,以上无论临时、缓存或者普通目录,如果不需要的数据,都请删除。不要占用用户的存储空间,像微信就是坏榜样。
下面是各路径对应的OC访问方法
app安装路径: [[NSBundle mainBundle] resourcePath]
app数据沙盒存储根目录: NSHomeDirectory()
Documents: NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
Library: NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)
Caches: NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)
tmp: NSTemporaryDirectory()
Android:
Application.dataPath /data/app/package name-1/base.apk
Application.streamingAssetsPath jar:file:///data/app/package name-1/base.apk!/assets
Application.temporaryCachePath /storage/emulated/0/Android/data/package name/cache
Application.persistentDataPath /storage/emulated/0/Android/data/package name/files
看Android上的路径,跟iOS有点类似,简单说一下。Android的几个目录是apk程序包、内存存储(InternalStorage)和外部存储(ExternalStorage)目录。
apk程序包目录: apk的安装路径,/data/app/package name-n/base.apk,dataPath就是返回此目录。
内部存储目录: /data/data/package name-n/,用户自己或其它app都不能访问该目录。打开会发现里面有4个目录(需要root)
cache 缓存目录,类似于iOS的Cache目录
databases 数据库文件目录
files 类似于iOS的Documents目录
shared_prefs 类似于iOS的Preferences目录,用于存放常用设置,比如Unity3D的PlayerPrefs就存放于此
外部存储目录: 在内置或外插的sd上,用户或其它app都可以访问,外部存储目录又分私有和公有目录。
公有目录是像DCIM、Music、Movies、Download这样系统创建的公共目录,当然你也可以像微信那样直接在sd卡根目录创建一个文件夹。好处嘛,就是卸载app数据依旧存在。
私有目录在/storage/emulated/n/Android/data/package name/,打开可以看到里面有两个文件夹cache和files。为什么跟内部存储目录重复了?这是为了更大的存储空间,以防内存存储空间较小。推荐把不需要隐私的、较大的数据存在这里,而需要隐私的或较小的数据存在内部存储空间。
下面是各路径对应的Java访问方法:
apk包内: AssetManager.open(String filename)
内部存储: context.getFilesDir().getPath() or context.getCacheDir().getPath()
外部存储: context.getExternalFilesDir(null).getPath() or context.getExternalCacheDir().getPath()
理解了Android存储的原理,最后来说说开头提到的bug,Application.temporaryCachePath/persistentDataPath返回空字符串。这其实因为权限的原因,app没有声明访问外部存储空间的权限,但是Application.temporaryCachePath/ ApplicationpersistentDataPath却想返回外部存储的路径。这是Unity3D的bug,没有权限本应该抛出一个异常或者错误,让开发者知道原因。
经反复测试发现,有【外置SD卡】的设备上,如果声明读/写外部存储设备的权限,会返回外部存储路径,不声明则会返回内部存储路径,这样不会有问题。而在【无外置SD卡】的设备上,不管是否声明读/写外部存储设备的权限,Application.temporaryCachePath/persistentDataPath都返回外部存储路径,但是又没有权限,就可能会导致返回null了,之所以说可能是因为这个bug不是必现,如果出现了设备重启之后就好了,怀疑是linux设备mount问题。但是出了问题,我们不能跟用户说你重启一下手机就好了。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Windows:
Application.dataPath: 应用的appname_Data/
Application.streamingAssetsPath: 应用的appname_Data/StreamingAssets
Application.temporaryCachePath: C:\Users\username\AppData\Local\Temp\company name\product name
Application.persistentDataPath: C:\Users\username\AppData\LocalLow\company name\product name
参考:
PS. 如果你对各平台文件管理或热更新有兴趣,欢迎一起讨论。
Unity3D各平台Application.xxxPath的路径的更多相关文章
- Unity3D移动平台动态读取外部文件全解析
前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...
- (转)Unity3D移动平台动态读取外部文件全解析
Unity3D移动平台动态读取外部文件全解析 c#语言规范 阅读目录 前言: 假如我想在editor里动态读取文件 移动平台的资源路径问题 移动平台读取外部文件的方法 补充: 回到目录 前言: 一直有 ...
- 慕容小匹夫 Unity3D移动平台动态读取外部文件全解析
Unity3D移动平台动态读取外部文件全解析 c#语言规范 阅读目录 前言: 假如我想在editor里动态读取文件 移动平台的资源路径问题 移动平台读取外部文件的方法 补充: 回到目录 前言: 一 ...
- Application中的路径
前提条件 项目工程目录:E:/Work/cosmosbox/cb-client/ 我电脑当前的用户名:qingqing PersistentDataPath Application.persisten ...
- Unity3d各平台资源路径文件夹
之前一直是PC项目,公司终于考虑移动平台了,但是试验了几把,感觉移动平台资源管理路径还是有很多隐藏的注意事项. 比如在PC上可以做到随便读写,但是在移动平台就涉及到权限问题. 看到小伙伴的总结,还是要 ...
- Unity3D 多平台 预编译 宏定义
平台定义 UNITY_EDITOR 编辑器调用. UNITY_STANDALONE_OSX 专门为Mac OS(包括Universal,PPC和Intelarchitectures)平台的定义. UN ...
- Unity3D 多平台_预编译相关宏定义
http://www.cnblogs.com/zhaoqingqing/p/3510332.html API地址:http://docs.unity3d.com/Documentation/Manua ...
- Qt配置信息设置(QSettings在不同平台下的使用路径)
在Windows操作系统中,大多把配置文件信息写在注册表当中,或写在*.ini文件中,对于这两种操作都有相应的Windows API函数,在以前的文章中都提及过,这里就不多说了~ 在Qt中,提供了一个 ...
- Application.CommonAppDataPath的路径
Application.CommonAppDataPath; win7的路径 C:\ProgramData\CompanyName\ProductName\2.0.5.1 [assembly: Ass ...
随机推荐
- line-height与图片底部间隙的学习整理转述
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 看大牛张鑫旭的视屏可能会理解的更深一些,点击这里: line-height,两行文字的基线之间的距离: 基 ...
- Django REST framework+Vue 打造生鲜超市(八)
九.个人中心功能开发 9.1.drf的api文档自动生成和 (1) url #drf文档,title自定义 path('docs',include_docs_urls(title='仙剑奇侠传')), ...
- thinkjs升级到3.0后的图片上传
似乎当thinkjs升级到3.0后,才接手了一个项目.只是在实际运用过程中,还是发现了与2.2的些许差别——今天先分享关于图片上传的一些问题. 1.上传文件,我们选择了jQuery的插件:http:/ ...
- BST讲解
BST 第一步,什么是BST,所谓BST就是满足一种特定性质的二叉树,这个性质一般情况是当前节点的权值比他的左子树的所有点的权值大,比他的右子树的所有点的权值小,满足这样性质的二叉树就称为BST,下面 ...
- for-each的坑(Hollis)
直接用代码来说明: public class ForEach { public static void main(String[] args) { List<String> list = ...
- [原创]手把手教你写网络爬虫(5):PhantomJS实战
手把手教你写网络爬虫(5) 作者:拓海 摘要:从零开始写爬虫,初学者的速成指南! 封面: 大家好!从今天开始,我要与大家一起打造一个属于我们自己的分布式爬虫平台,同时也会对涉及到的技术进行详细介绍.大 ...
- [BJOI 2010]次小生成树Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- 51 nod 1394 1394 差和问题(线段树)
1394 差和问题基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个多重集合S(即里面元素可以有重复),初始状态下有n个元素,对他进行如下操作: 1.向S里面添 ...
- Gradle学习之构建java与web项目
一.使用Gradle的java插件构建Java项目 1)Gradle插件包含了若干个接口定义和已有的任务项,语法结构:apply plugin:'插件名' ,此处我们定义插件 apply plugin ...
- Python 线程池,进程池,协程,和其他
本节内容 线程池 进程池 协程 try异常处理 IO多路复用 线程的继承调用 1.线程池 线程池帮助你来管理线程,不再需要每个任务都创建一个线程进行处理任务. 任务需要执行时,会从线程池申请线程,有则 ...