Json格式存储 Unity本地数据存储

发布于 2023-01-25  503 次阅读


知乎:活着就好啦 B站:BeaverJoe

【【中文字幕】使用JSON方式保存和读取Unity数据信息(四种保存读取数据方法系列第三期)】 https://www.bilibili.com/video/BV157411x7qZ/?share_source=copy_web&vd_source=1e6de1b65319e041939801e8eea80cb7

数据持久化-认识Json与JsonUtlity(1) - 活着就好啦的文章 - 知乎 https://zhuanlan.zhihu.com/p/513432977

Json

JSON(JavaScript Object Notation)一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。

JSON采用兼容性很高的、完全独立于语言文本格式,同时也具备类似于C语言的习惯体系的行为。这些特性使JSON成为理想的数据交换语言。

JSON语法是javaScript语法的子集,javaScript用【】中括号来表示数组,用{}大括号来表示对象,JSON亦是如此。

优点

  • 解析速度快,数据格式比较简单,易于读写,格式都是压缩的,占用带宽小。
  • 支持多种语言,便于服务器端的解析。
  • 因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。

在JSON里面,注释跟正常的C#语言一样,“//”表示单行注释,“/**/”表示多行注释,因为Json最大的特点就是键值对,所以有个小知识就是作为值的值类型可以是null,这个在JSON是支持的,然后JSON文本的编码必须是UTF-8否则是会报错的。

JsonUtility

JsonUtlity是Unity自带的用于解析Json的公共类,它可以将内存对象序列化为Json格式的字符串,该能将Json字符串反序列化为类对象。

新建类

public class XiaoXiaoZe
    {
        public string name;
        public int age;
        public bool sex;
        public float testFloat;
        public double testDouble;

        public int[] ids;
        public List<int> ids2;
        public Dictionary<int, string> dic;
        public Dictionary<string, string> dic2;

        // 对于我们自己定义的类,我们在对它们进行序列化之前需要在类的前面加上[System.Serializable]特性
        public Human human;
        public List<Human> humans;

        [SerializeField]// 想要序列化私有变量 需要加上特性[SerializeField]
        private int privateI = 1;
        [SerializeField]// 想要序列化私有变量 需要加上特性[SerializeField]
        protected int protectedI = 2;
    }

    [System.Serializable]
    public class Human
    {
        public int age;
        public string name;

        public Human(int age, string name)
        {
            this.age = age;
            this.name = name;
        }
    }

private void Start()
    {
        // 3.使用JsonUtlity进行序列化(序列化:把内存数据存储到硬盘上)
        XiaoXiaoZe xxz = new XiaoXiaoZe();
        xxz.name = "小小泽";
        xxz.age = 999;
        xxz.sex = true;
        xxz.testFloat = 1.4f;
        xxz.testDouble = 1.4;

        xxz.ids = new[] { 1, 2, 3, 4 };
        xxz.ids2 = new List<int>() { 1, 2, 3 };
        xxz.dic = new Dictionary<int, string>() { { 1, "123" }, { 2, "234" } };
        xxz.dic2 = new Dictionary<string, string>() { { "1", "123" }, { "2", "234" } };

        // 对于我们自己定义的类,我们在对它们进行序列化之前需要在类的前面加上[System.Serializable]特性
        xxz.human = null;// 这里是为了测试NUll类型
        xxz.humans = new List<Human>() { new Human(2, "小明"), new Human(3, "小强") };
}

将对象转换为json

// JsonUtility提供了现成的方法可以把类对象序列化为Json字符串
string jsonStr = JsonUtility.ToJson(xxz);

//写入文件
File.WriteAllText(Application.persistentDataPath + "/XXZ.json", jsonStr);

从文件数据读出

//使用JsonUtlity进行反序列化(把硬盘数据存储到内存里)
text = File.ReadAllText(Application.persistentDataPath + "/XXZ.json");
​
// 第一种写法
XiaoXiaoZe xxz2 = JsonUtility.FromJson(text, typeof(XiaoXiaoZe)) as XiaoXiaoZe;
// 第二种写法
xxz2 = JsonUtility.FromJson<XiaoXiaoZe>(text);
print(xxz2.name);
print(xxz2.age);
print(xxz2.sex);

注意

  • 字典是无法支持序列化的
  • Float类型出现了很多位数的小数部分(其实这个没有什么大问题,因为我们最终反序列化的结果是正确的就行)
  • 我们自定义的类即使是null,序列化之后也会存储自定义类内部字段类型的默认值(跟xml不一样,xml是不会存储)
  • 自定义类需要加上序列化特性[System.Serializable]
  • 想要序列化私有变量 需要加上特性[SerializeField]