unity中application(3D自动保存路径)

iOS/Android/Windows平台应用存储路径,Unity3D在各平台的路径,Application.dataPath/Application.streamingAssetsPath/Application.temporaryCachePath/Application.persistentDataPath

大家好,又见面了,我是你们的朋友全栈君。

前几天我们游戏在一个同事的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


PlayerPrefs路径(补充)

Android: /data/data/pkg-name/shared_prefs/pkg-name.v2.playerprefs.xml
iOS:/Library/Preferences/[bundle identifier].plist
Windows:HKEY_CURRENT_USER/Software/CompanyName/ProductName
Mac:~/Library/Preferences/com.CompanyName.ProductName.plist


参考:

  1. iOS Data Storage Guidelines
  2. Android API: Storage Options
  3. 彻底理解Android中的内部存储与外部存储
  4. Unity – Scripting API:PlayerPrefs

PS. 如果你对各平台文件管理或热更新有兴趣,欢迎一起讨论。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126965.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vue filters过滤器的统一封装「建议收藏」

    vue filters过滤器的统一封装「建议收藏」目录统一封装规则统一封装规则1、src文件夹下创建filters文件夹,然后再filters文件夹下创建index.js即:src/filters/index.js2、在main.js中引入src/filters/index.js文件,并在下方遍历调用filters中的方法,使用VUE.filters切记:将遍历代码写在newVUE()上方3、在src/utils文件夹下的文件中创建各种工具类方法4、在src/filters/index.js中引入utils中的方法进行调用src

    2022年5月22日
    37
  • Microsoft Platform SDK Febrary 2003 Edition 下载地址与下载方式「建议收藏」

    Microsoft Platform SDK Febrary 2003 Edition 下载地址与下载方式「建议收藏」今天上网找windowssdk,发现最新的SDK已经不支持vc6.0,在微软官方站下看到下面一段话。DevelopmentTools.TobuildtheC/C++samples,youmusthaveaC/C++compiler.IfyouareusingMicrosoftVisualC/C++®,runitatleastoncebe

    2022年5月23日
    40
  • 动态规划之背包问题(C语言)

    动态规划之背包问题(C语言)动态规划动态规划(英语:Dynamicprogramming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题动态规划思想大致上为:若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。由于通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算

    2022年7月14日
    24
  • C# SortedList类概念和示例

    SortedList类[C#]命名空间:System.Collections表示键/值对的集合,这些键和值按键排序并可按照键和索引访问。SortedList是Hashtable和A

    2021年12月21日
    39
  • WPF Visifire 入门-动态曲线图[通俗易懂]

    WPF Visifire 入门-动态曲线图[通俗易懂]kagula2019-3-18这里用源代码的形式,示范如何画出一个最简单的动态曲线图。开发环境,Visualstudio2017CommunityUpdate5项目类型:WPFC#.NetFramework4.6.1本文适用对象:有两年没有开发C#WPF的程序员,通过这个示例可以快速回忆。下面是运行效果图,不停显示最新生成的十个数据点。让…

    2022年7月21日
    13
  • 进销存excel_用Excel制作简单的进销存系统「建议收藏」

    进销存excel_用Excel制作简单的进销存系统「建议收藏」最近刚好帮一个朋友做一个进销存系统,因为使用者对电脑操作以及Excel应用能力较弱,我做的进销存系统没有用特别复杂的功能,非常有解决意义,我将手把手将你制作一个简单的进销存系统。需求描述朋友找人合伙开了一个女装店,想要用Excel记录每天的销售数据、定期的进货数据,以及定期盘点库存情况。朋友的合伙人对电脑操作、Excel数据管理能力较弱,前期购买过专用的进销存软件,但是经常会把数据搞乱,因此放弃了…

    2022年5月31日
    55

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号