数据持久化问题

前言

有时候有数据长久保存的需求,不受应用开关的影响。Unity通过PlayerPrefs类来进行数据持久化保存,可以保存int、float以及string类型,对于复杂数据结构可以转化成json,然后保存。

1.PlayerPrefs

unity提供了三个方法来实现数据持久化,不过只能对int float string类型进行数据持久化,命令如下:

//设定Key=float的值为12f
        PlayerPrefs.SetFloat("float", 12f);
        //通过key值“float”获取数值12,如果“float”未设定值,则默认为1f
        PlayerPrefs.GetFloat("float", 1f);
        //相关定义与setfloat相同
        PlayerPrefs.SetInt("int", 12);
        PlayerPrefs.GetInt("int", 1);
        PlayerPrefs.SetString("str", "abc");
        PlayerPrefs.GetString("str", "default");

2.Xml文件保存

2.1 编写xml

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;

namespace MenuData
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "";
            string fileName = "MenuData.xml";
            string targetFile = Path.Combine(filePath, fileName);

            string[] mainMenu = new string[]{
                 "文件","配置","显示","诊断","投入运行","关机","帮助"};
            string[] parentMenu = new string[]
            {
                 "投入运行助手","测量","调整","软件更新","售后服务","机器人数据","网络配置","辅助软件"
            };

            string[] childMenu = new string[]
{
                 "工具","基坐标","固定工具","附加负载数据","外部运动装置","测量点","允差"
};
            string[] toolMenu = new string[]
            {
                 "XYZ_4点法","XTZ_参照法","ABC_2点法","ABC_世界坐标系","数字输入","更改名称","工具负荷数据"
            };
            string[] baseMenu = new string[]
{
                 "_3点法","间接","数字输入","更改名称"
};
            XmlDocument xmldoc = new XmlDocument();
            //加入XML的声明段落,<?xml version="1.0" encoding="gb2312"?>
            XmlDeclaration xmldecl;
            xmldecl = xmldoc.CreateXmlDeclaration("1.0", "gb2312", null);
            xmldoc.AppendChild(xmldecl);

            XmlElement menu = xmldoc.CreateElement("", "Menu", "");
            xmldoc.AppendChild(menu);

            //XmlNode root = xmldoc.SelectSingleNode("Menu");//查找<menu> 
            for (int i = 0; i < mainMenu.Length; i++)
            {
                XmlElement rootElem = xmldoc.CreateElement(mainMenu[i]);//创建一个<mainMenu[i]>节点 
                rootElem.SetAttribute("Layer", "1");//设置该节点ID属性 
                if (i == 4)
                {
                    for (int j = 0; j < parentMenu.Length; j++)
                    {
                        XmlElement parentElem = xmldoc.CreateElement(parentMenu[j]);//创建一个<parentElem[i]>节点 
                        parentElem.SetAttribute("Layer", "2");//设置该节点ID属性 
                        if (j == 1)
                        {
                            for (int m = 0; m < childMenu.Length; m++)
                            {
                                XmlElement childElem = xmldoc.CreateElement(childMenu[m]);//创建一个<childMenu[i]>节点 
                                childElem.SetAttribute("Layer", "3");
                                if (m == 0)
                                {
                                    for (int ii = 0; ii < toolMenu.Length; ii++)
                                    {
                                        XmlElement elem = xmldoc.CreateElement(toolMenu[ii]);//创建一个<childMenu[i]>节点 
                                        elem.SetAttribute("Layer", "4");
                                        //  elem.InnerText = toolMenu[ii];
                                        childElem.AppendChild(elem);
                                    }
                                }
                                if (m == 1)
                                {
                                    for (int ii = 0; ii < baseMenu.Length; ii++)
                                    {
                                        XmlElement elem = xmldoc.CreateElement(baseMenu[ii]);//创建一个<childMenu[i]>节点 
                                        elem.SetAttribute("Layer", "4");                                                                   //   elem.SetAttribute("type", "noChild");
                                        //elem.InnerText = baseMenu[ii];
                                        childElem.AppendChild(elem);
                                    }
                                }
                                parentElem.AppendChild(childElem);
                            }
                        }
                        rootElem.AppendChild(parentElem);
                    }
                }

                menu.AppendChild(rootElem);
            }
            xmldoc.Save(targetFile);
            Console.ReadKey();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace XmlRW
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument  xmldoc = new XmlDocument();
            //加入XML的声明段落,<?xml version="1.0" encoding="gb2312"?>
            XmlDeclaration xmldecl;
            xmldecl = xmldoc.CreateXmlDeclaration("1.0", "gb2312", null);
            xmldoc.AppendChild(xmldecl);

            //加入一个根元素
            XmlElement xmlelem = xmldoc.CreateElement("", "ToolAndFrame", "");
            xmldoc.AppendChild(xmlelem);
       
            for (int i = 1; i < 3; i++)
            {
                string identifyStr;
                string id;
                int count;
                if(i==1)
                {
                    identifyStr = "tool";
                    count = 16;
                }
                else
                {
                    identifyStr = "frame";
                    count = 32;
                }
                //增加次级节点
                XmlNode root = xmldoc.SelectSingleNode("ToolAndFrame");//查找<ToolAndFrame> 
                XmlElement elem = xmldoc.CreateElement(identifyStr);//创建一个<identifyStr>节点 
                elem.SetAttribute("ID", identifyStr);//设置该节点ID属性 
                //xe1.SetAttribute("ISBN", "2-3631-4");//设置该节点ISBN属性 

                for(int j=0;j<count;j++)
                {
                    XmlElement toolElem = xmldoc.CreateElement("elem"+i.ToString());
                    toolElem.SetAttribute("ID", j.ToString());
                    toolElem.InnerText = "未知        [?]";
                    elem.AppendChild(toolElem);
                }

                root.AppendChild(elem);//添加到<Employees>节点中 
            }
            xmldoc.Save("ToolAndFrame.xml");
        }
    }
}

2.2 读取

如果xml需要跳过注释可用:

 if(temp is XmlComment)
            {
                continue; 
            }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ReadXml
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("ToolAndFrame.xml");
            List<string> strList = new List<string>();
            XmlNodeList nodeList = xmlDoc.SelectSingleNode("ToolAndFrame").ChildNodes;//获取Employees节点的所有子节点 

            foreach (XmlNode temp in nodeList)//遍历所有子节点 
            {
                XmlElement elem = (XmlElement)temp;//将子节点类型转换为XmlElement类型 
                //if (elem.GetAttribute("genre") == "张三")//如果genre属性值为“张三” 
                //{
                //    elem.SetAttribute("genre", "update张三");//则修改该属性为“update张三” 
                //}
                XmlNodeList childElem = elem.ChildNodes;//继续获取xe子节点的所有子节点 
                foreach (XmlNode node in childElem)//遍历 
                {
                    XmlElement xml = (XmlElement)node;//转换类型 
                    //if (xml.Name == "author")//如果找到 
                    //{
                    //    xml.InnerText = "亚胜";//则修改
                    //}
                    strList.Add(xml.InnerText);
                }
            }

            foreach(string str in strList)
            {
                Console.WriteLine(str);
            }
            Console.WriteLine(strList.Count);
            Console.ReadKey();
        }
    }
}

2.3 查找与更改

本文查找与更改只是更改了属性,如果需要添加节点或者删除节点,只需要查找到相关节点以后,用命令remvoechild即可,最后一定要保存。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ChangeText
{
    class Program
    {
        static void Main(string[] args)
        {
            string id = "tool";
            int num = 7;
            string text = "new Name";
            ChangeVal(id, num, text);            
        }
        public static void ChangeVal(string id,int num,string text)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("ToolAndFrame.xml");
          //  List<string> strList = new List<string>();
            XmlNodeList nodeList = xmlDoc.SelectSingleNode("ToolAndFrame").ChildNodes;//获取Employees节点的所有子节点 

            foreach (XmlNode temp in nodeList)//遍历所有子节点 
            {
                XmlElement elem = (XmlElement)temp;//将子节点类型转换为XmlElement类型 
                if (elem.Name == id)//如果elem的名字为“张三” 
                {
                    Console.WriteLine(elem.GetAttribute("ID"));
                    Console.WriteLine(elem.Name);

                    XmlNodeList childElem = elem.ChildNodes;//继续获取xe子节点的所有子节点 
                    foreach (XmlNode node in childElem)//遍历 
                    {
                        XmlElement xml = (XmlElement)node;//转换类型 
                        if (xml.GetAttribute("ID") == num.ToString())
                        {
                            xml.InnerText = text;
                            break;
                        }
                    }
                    break;
                }         
            }
            xmlDoc.Save("ToolAndFrame.xml");
            Console.ReadKey();
        }
    }
}

3.JsonUtility

3.1 通用方法

如果采用json格式实现数据可持续化则可以直接采用unity方法jsonUtility来实现。

private string WriteTOJson()
    {
        string json = JsonUtility.ToJson(jsonData);
        return json;
    }
    private PersistData ReadFromJson(string json)
    {
        PersistData jsonClass = JsonUtility.FromJson<PersistData>(json);
        return jsonClass;
    }
class PersistData
    {
        public long width;
        public long top;
        public long left;
        public long height;
    }

3.2 List

对于list格式的参数进行解析时要增加serializable,同时还需要构建一个带list的类,通过此类来间接解析。

#region jsonClass
[Serializable]
public class ListModel
{
    public int ListContentId;
    public string CName;//新版本
    public string EName;//新版本
    //public string Name;//旧版本
    public string BigResourcePath;
    public string BigResourceName;
    public string BigResourceType;
    public string SmallResourcePath;
    public string SmallResourceName;
    public string SmallResourceType;
    public DateTime UpdateTime;
    public int Order;
    public int Level;
    public int ParentId;
}
[Serializable]
public class ListLevelModel
{
    public bool success;

    public List<ListModel> data;
}

#endregion
listLevelModel = JsonUtility.FromJson<ListLevelModel>(jsonlist);  

4.Litjson

Litjson是一个开源,更强大的json解析工具,可以解析成一个类对象,也可直接解析出List和Dictionary。

4.1 解析List或Dictionary

List:

allComments = JsonMapper.ToObject<List<CommentElem>>(json);

Dictionary:

Dictionary<string, object> itemDataDic = JsonMapper.ToObject<Dictionary<string, object>>(json);

Dictionary也可以如下解析:

          JsonData jsonData = JsonMapper.ToObject(json);

            foreach (JsonData item in jsonData)
            {
                 //TODO 直接解析
                if (item.Keys.Contains("SSID"))
                {
                    itemData.SSID = item["SSID"].ToString();
                }
            }

4.2 直接解析

可以直接解析出所需要的参数,如下所示,可以直接获取到det下add的值

JsonData data = JsonMapper.ToObject(json);
string str = data["Det"]["add"].ToString();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值