Unity API——Application类的详解(二):数据文件路径

上一节中将Application类中所有的静态属性和静态方法都一一列举,方便以后查阅。接下将详细介绍Application类的属性和方法。
上一节传送门:Unity API——Application类的详解(一):列举属性和方法


数据文件路径:总共有四个属性,分别为:dataPath、persistentDataPath、streamingAssetsPath、 temporaryCachePath


基本语法:public static string dataPath { get ;}

dataPaht是包含游戏数据文件夹的路径,权限为只读,返回的是一个相对路径,即对于不同的游戏平台返回的路径是不一样的。
Unity Editor: <path tp project folder>/Assets
Mac player: <path to player app bundle>/Contents
iOS player: <
path to player app bundle
>/<
AppName.app
>/Data
Android:/data/app/xxx.xxx.xxx.apk

测试代码:

using UnityEngine;
using System.Collections;
/// <summary>
/// 此类用于 dataPath测试
/// </summary>
public class DataPath : MonoBehaviour 
{
    private void printDataPath()
    {
        Debug.Log("dataPaht:" + Application.dataPath);
    }
    void Start () 
    {
        printDataPath();
    }
    
}

由于设备和条件有限,我只在Unity Editor 和android两个环境下作了测试,测试结果如下:

  • Unity Editor测试结果:
Unity Editor 控制台打印出的日志
  • Android平台测试结果:
LogCat下打印的日志

注意

Application.dataPath 返回的路径目录,在移动端是没有访问权限的(既不能访问此目录)。


基本语法:public static string persistentDataPath{ get ;}

persistentDataPaht返回的是一个持久化数据存储目录,权限为只读,在同一平台,不用的应用程序访问此属性返回值相同,但是不同的平台就不相同了。当应用程序发布到IOS和Android平台中,这个路径会指向一个公共的路径,而且应用每次更新时这里的数据不会被清除。

测试代码:

using UnityEngine;
using System.Collections;
/// <summary>
/// 此类用于 persistentDataPath测试
/// </summary>
public class DataPath : MonoBehaviour 
{

    private void printPersistentDataPaht()
    {
        Debug.Log("persistentDataPaht:" + Application.persistentDataPath);
    }
    void Start () 
    {
        printPersistentDataPaht();
    }

    
}


  • Unity Editor测试结果:
Unity Editor 控制台打印出的日志
  • Android平台测试结果:

LogCat下打印的日志

注意

这个路径比较特殊,这个路径下是可读写。而且在IOS上就是应用程序的沙盒,但是在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。该路径的特点:

  • 内容可读写,不过只能运行时才能写入或者读取。提前将数据存入这个路径是不可行的。
  • 无内容限制。你可以从StreamingAsset中读取二进制文件或者从AssetBundle读取文件来写入PersistentDataPath中。
  • 写下的文件,可以在电脑上查看。同样也可以清掉。

基本语法:public static string streamingAssetsPath{ get ;}

streamingAssetsPath返回的是流数据的缓存目录,返回路径为相对路径适合用来存储一些外部数据文件。

测试代码:

using UnityEngine;
using System.Collections;
/// <summary>
/// 此类用于 streamingAssetsPath测试
/// </summary>
public class DataPath : MonoBehaviour 
{
    private void printStreamingAssetsPaht()
    {
        Debug.Log("streamingAssetsPaht:" + Application.streamingAssetsPath);
    }

    void Start () 
    {
        printStreamingAssetsPaht();
    }
}


  • Unity Editor测试结果:
Unity Editor 控制台打印的日志
  • Android平台测试结果:
Logcat打印的日志

基本语法:public static string temporaryCachePath{ get ;}

temporaryCachePath返回一个临时数据缓存目录(只读),同一平台不用应用程序访问此属性的返回值相同,不同平台返回值不同。

测试代码:

using UnityEngine;
using System.Collections;
/// <summary>
/// 此类用于 temporayrCachePaht测试
/// </summary>
public class DataPath : MonoBehaviour 
{
    private void printTemporaryCachePath()
    {
        Debug.Log("temporaryCachePaht:" + Application.temporaryCachePath);
    }

    void Start () 
    {
        printTemporaryCachePath();
    }

}


  • Unity Editor测试结果:
Unity Editor 控制台打印的日志
  • Android平台测试结果:
LogCat打印的日志

将以上四个路径分别在Unity Editor和Android环境下进行一个对比:

  • Unity Editor 平台
    dataPath:      D:/unity/workSpace/MyReadBook/Assets
    persistentDataPath:  C:/Users/young/AppData/LocalLow/young/datapahttest
    streamingAssetsPath: D:/unity/workSpace/MyReadBook/Assets/StreamingAssets
    temporaryCachePath: C:/Users/young/AppData/Local/Temp/young/datapahttest
  • Android 平台
    dataPath:       /data/app/com.young.datapahttest-1.apk
    persistentDataPath:   /data/data/com.young.datapahttest/files
    streamingAssetsPath:  jar:file:///data/app/com.young.datapahttest-1.apk!/assets
    temporaryCachePath:  /data/data/com.young.datapahttest/cache

从中可以看出,dataPath 和 stremingAssetsPath是相对于程序的安装目录,是相对路径。非常适用于移植平台设置外部数据文件读取路径。而persistentDataPath和temporaryCachePath返回的程序所在平台的固定位置。适用于存储程序运行过程中一些数据。

总结:


  • 四个路径的含义
属性名称 含义
Application.dataPath 此属性用于返回程序的数据文件所在文件夹的路径
Application.streamingAssetsPath 此属性用于返回流数据的缓存目录,返回路径为相对路径,适合设置一些外部数据文件的路径。
Application.persistentDataPath 此属性用于返回一个持久化数据存储目录的路径,可以在此路径下存储一些持久化的数据文件:
Application.temporaryCachePath 此属性用于返回一个临时数据的缓存目录。
  • Android 平台
属性名称 返回路径
Application.dataPaht /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
Application.persistentDataPath /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath /data/data/xxx.xxx.xxx/cache
  • IOS 平台
属性名称 返回路径
Application.dataPaht Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
  • Unity Editor平台
属性名称 返回路径
Application.dataPaht Application(工程目录)/Assets
Application.streamingAssetsPath Application(工程目录)/Assets/StreamingAssets
Application.persistentDataPath 系统指定目录1/工程名
Application.temporaryCachePath 系统指定目录2/工程名

扩展:Unity资源处理(参考了:Unity3D移动平台动态读取外部文件全解析

关于资源加载问题要讲到ResourcesStreamingAssetsAssetBundle这三个类。

Resources:
它作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。其特点是:

  • 只读,即不能动态修改。所以想要动态更新的资源不要放在这里。
  • 会将文件夹内的资源打包集成到.asset文件里面。因此建议可以放一些Prefab,因为Prefab在打包时会自动过滤掉不需要的资源,有利于减小资源包的大小。
  • 主线程加载。
  • 资源读取使用Resources.Load()。

实例测试

  • 首先新建一个用于测试的text.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<test>
    <name>young</name>
    <blog>http://www.jianshu.com/users/afda32f1cc9a/latest_articles</blog>
    <age>21</age>
    <address>China</address>
</test>
  • 然后在Assets文件夹下新建一个Resources目录,将text.xml放在改目录下,如下图所示:
  • 新建一个脚本ReadXMLInResources.cs挂在Main Camera下,脚本代码如下:
using UnityEngine;
using System.Collections;
using System.Xml;


/// <summary>
/// 此类用于测试 在Resources目录下读取XML文件
/// </summary>
public class ReadXMLInResources : MonoBehaviour
{

    private string readXMLResult;

    // Use this for initialization
    void Start () {
        LoadXML("text");
        Debug.Log("xml:" + readXMLResult);
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }

    void OnGUI()
    {
        GUIStyle titleStyle = new GUIStyle();
        titleStyle.fontSize = 20;
        titleStyle.normal.textColor = new Color(0, 255, 255);
        GUI.Label(new Rect(400, 10, 500, 200), readXMLResult, titleStyle );
    }

    /// <summary>
    /// 加载Assets/Resources文件夹下resourcesName文件
    /// </summary>
    /// <param name="resourcesName"></param>
    private void LoadXML(string resourcesName)
    {
        readXMLResult = Resources.Load(resourcesName).ToString();

        XmlDocument doc = new XmlDocument();

        doc.LoadXml(readXMLResult);
    }



}

    1. 在WindowEditor平台下运行结果:
WindowsEditor运行结果截图
  • 2 在Android平台下运行结果:
Andorid平台下运行结果截图

StreamingAssets:
要说到StreamingAssets,其实和Resources还是蛮像的。同样作为一个只读的Unity3D的保留文件夹出现。不过两者也有很大的区别,那就是Resources文件夹中的内容在打包时会被压缩和加密。而StreamingAsset文件夹中的内容则会原封不动的打入包中,因此StreamingAssets主要用来存放一些二进制文件。下面也同样做一个简单的总结:

  • 只读不可写。
  • 主要用来存放二进制文件。
  • Android平台下一般是通过过WWW类来读取。

实例测试

-首先在Assets目录下新建StreamingAssets文件夹,将text.xml放入改目录下(此例金座测试,实际数据文件一般不会放在改文件夹下)如下图所示:

Paste_Image.png
  • 然后创建一个ReadXMLInStreamingAssets.cs脚本 挂在Main Camera下,脚本代码如下:
using UnityEngine;
using System.Collections;
using System.IO;

public class ReadXMLInStreamingAssets : MonoBehaviour
{
    /// <summary>
    /// 读取XML结果
    /// </summary>
    private string readXmlResult;

    // Use this for initialization
    void Start ()
    {
        loadXML();
        Debug.Log(readXmlResult);
    }
    
    // Update is called once per frame
    void Update () {
    
    }


    void OnGUI()
    {
        GUIStyle titleStyle = new GUIStyle();
        titleStyle.fontSize = 20;
        titleStyle.normal.textColor = new Color(0, 255, 255);
        GUI.Label(new Rect(400, 10, 500, 200), readXmlResult, titleStyle);
    }


    /// <summary>
    /// 根据不同的平台加载StremingAssets文件夹下的XML文件
    /// </summary>
    private void loadXML()
    {
        if(Application.platform == RuntimePlatform.Android)
        {
            Debug.Log("android platform");
            StartCoroutine("loadXMLWithWWW");
        }
        else if(Application.platform == RuntimePlatform.WindowsEditor)
        {
            Debug.Log("window platform");
            //获得文件路径
            string path = Application.streamingAssetsPath + "/text.xml";
            loadXMLWithStreamReader(path);
        }
        else if(Application.platform == RuntimePlatform.IPhonePlayer)
        {
            Debug.Log("iphone platform");
            //获得文件路径
            string path = Application.streamingAssetsPath +"/text.xml";
            loadXMLWithStreamReader(path);

        }
        //发现所有平台StreamingAssets目录下的文件路径都可以用Application.streamingAssetsPath +"/fileName.xml"来加载,但Android加载方式不一样
    }

    /// <summary>
    /// 使用StreamReader读取文件信息
    /// </summary>
    /// <param name="path">读取文件的路径</param>
    private void loadXMLWithStreamReader(string path)
    {  
        FileInfo fileInfo = new FileInfo(path);
        StreamReader reader = fileInfo.OpenText();
        readXmlResult = reader.ReadToEnd();
        reader.Close();
    }

    /// <summary>
    /// 
    ///对于android平台, streamingAssets中的文件一般只能用www来异步读取
    /// (同时,可以用persistenDataPath来保存streamingassets里读取的数据)
    /// </summary>
    /// <returns></returns>
    IEnumerator loadXMLWithWWW()
    {
        //获得文件路径
        string path = Application.streamingAssetsPath + "/text.xml";
        WWW www = new WWW(path);

        yield return www;

        readXmlResult = www.text;

    }
}

    1. 在WindowEditor平台下运行结果:
WindowEditor平台下运行结果截图
  • 2 在Android平台下运行结果:

Android平台下运行结果截图

AssetBundle
是把prefab或者二进制文件封装成AssetBundle文件(也是一种二进制)。但是也有硬伤,就是在移动端无法更新脚本。下面简单的总结下:

  • 是Unity3D定义的一种二进制类型。
  • 最好将prefab封装成AseetBundle,不过上面不是才说了在移动端无法更新脚本吗?那从Assetbundle中拿到的Prefab上挂的脚本是不是就无法运行了?也不一定,只要这个prefab上挂的是本地脚本,就可以。
  • 使用WWW类来下载。

实例测试

待续。。。

特别说明:

本文案例工程使用的Unity编辑器版本为5.1.1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容