【保举100个unity插件之37】unity使用三种方式实现对Json数据的序列化和反 ...

打印 上一主题 下一主题

主题 866|帖子 866|积分 2608

前言

unity对Json数据的序列化和反序列化着实之前已经做过很多了,但是都是零零散散,并没有举行系统的整理,这次我专程单独拿出来讲讲。
传送门:
【unity框架开发12】从零手搓unity存档存储数据长期化系统,实现对存档的创建,获取,保存,加载,删除,缓存,加密,支持多存档(2024/11/23补充)
【保举100个unity插件之20】一个强大的JSON处理惩罚库——Newtonsoft.Json(也称为Json.NET)
【unity框架开发12】从零手搓unity存档存储数据长期化系统,实现对存档的创建,获取,保存,加载,删除,缓存,加密,支持多存档(2024/11/23补充)
一、前置知识

1、获取各种文件路径

Application.persistentDataPath获取的是一个长期化的数据路径,在不同的使用系统上,unity会为我们分配不同的长期化数据路径,这样可以确保应用程序在不同平台上都能正确保存和访问
  1. //设置存档文件路径
  2. savePath = Path.Combine(Application.persistentDataPath, "saveData.json");
复制代码
不同平台存储的路径不一样,我们可以打印savePath查看自己的存储路径
比如我PC上的就是

其他:https://blog.csdn.net/qq_36303853/article/details/129688513
2、将字符串存入文件中

File.WriteAllText()将字符串写入到指定路径文件中


  • 第一个参数填写的是存储的路径
  • 第二个参数填写的是存储的字符串内容
  • 注意:第一个参数必须是存在的文件路径如果没有对应文件夹会报错
  1. File.WriteAllText(Application.persistentDataPath + "/Test.json", "json文件");
复制代码
3、读取文件中的字符串内容

  1. string str = File.ReadAllText(Application.persistentDataPath + "/Test.json");
复制代码
4、什么是序列化和反序列化



  • 序列化着实就是把内存中的数据存储到硬盘上
  • 反序列化着实就是把硬盘上的数据读取到内存中

二、JsonUtlity

1、JsonUtlity是什么?

JsonUtlity是Unity自带的用于分析Json的公共类
它可以:


  • 将内存中对象序列化为Json格式的字符串
  • 将Json字符串反序列化为类对象
2、注意



  • float序列化时看起来会有一些误差,但是读取着实不影响
  • 自界说类必要加上序列化特性[System.Serializable]
  • 想要序列化私有变量必要加上特性[SerializeField]
  • JsonUtlity可以序列化vector Color Quaternion等数据
  • JsonUtlity不支持字典
  • JsonUtlity存储null数据不会是null,而是默认值,比如string就会是空字符""
3、实例

界说一些不同类型的数据

  1. public class Data{
  2.     public string name = "小明";
  3.     public string name2 = null;
  4.     public int age = 12;
  5.     public float height = 1.85f;
  6.     public int[] ids = {1, 2, 3};
  7.     public List<int> list = new List<int>{11, 22, 33};
  8.     public Dictionary<int, string> intDic = new Dictionary<int, string>{{1, "内容1"}, {2, "内容2"}, {3, "内容3"}};
  9.     public Dictionary<string, string> strDic = new Dictionary<string, string>{{"key1", "内容1"}, {"key2", "内容2"}, {"key3", "内容3"}};
  10.     public Son son2 = new Son("子数据", 1);
  11.     public List<Son> listSon = new List<Son>{new Son("数据1", 1), new Son("子数据2", 2)};
  12.     public Vector3 vector3 = new Vector3(1, 2, 1);
  13.     public Color color = Color.red;
  14.     public Quaternion rotation = Quaternion.Euler(0f, 90f, 0f);
  15.     [SerializeField]
  16.     private int privateInt = 66;
  17.     [SerializeField]
  18.     protected int protectedInt = 77;
  19.     public override string ToString()
  20.     {
  21.         string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
  22.                         $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
  23.                         $"IntDic: {string.Join(", ", intDic)}, StrDic: {string.Join(", ", strDic)}\n" +
  24.                         $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n" +
  25.                         $"vector3: {vector3}, color: {color}, rotation: {rotation}\n" +
  26.                         $"privateInt: {privateInt}, protectedInt: {protectedInt}";
  27.         return result;
  28.     }
  29. }
  30. [System.Serializable]
  31. public class Son{
  32.     public string name;
  33.     public int age;
  34.     public Son(string name, int age){
  35.         this.name = name;
  36.         this.age = age;
  37.     }
  38. }
复制代码
使用JsonUtility.ToJson举行序列化

  1. Data data = new Data();
  2. string jsonData = JsonUtility.ToJson(data);
  3. File.WriteAllText(Application.persistentDataPath + "/Test.json", jsonData);
复制代码
存储结果
可以看到如前面所说,字典无法存储,float类型存储有些误差,null数据存储的是默认值

使用JsonUtlity举行反序列化

  1. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  2. Data data2 = JsonUtility.FromJson<Data>(jsonStr);
  3. print(data2.ToString());
复制代码
打印结果,这里还是有打印出字典的原因是因为,字典数据没有读取到,所以输出了默认值

4、JsonUtility不能直接将数据反序列化为数据集合

比如我们想读取这样的数组json数据

界说数据
  1. public class Data1
  2. {
  3.     public string name;
  4.     public int age;
  5.    
  6.     public override string ToString()
  7.     {
  8.         string result = $"name: {name}, age: {age}";
  9.         return result;
  10.     }
  11. }
复制代码
读取
  1. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  2. List<Data1> data2 = JsonUtility.FromJson<List<Data1>>(jsonStr);
  3. print(data2[0].ToString());
复制代码
结果直接会报错

5、总结



  • File存读字符串的方法ReadAllText和WriteAllText
  • JsonUtility提供的序列化反序列化方法ToJson和FromJson
  • 自界说类必要加上序列化特性[System.Serializable]
  • 想要序列化私有变量必要加上特性[SerializeField]
  • JsonUtility不支持字典
  • JsonUtility不能直接将数据反序列化为数据集合
  • Json文档编码格式必须是UTF-8

三、LitJSON

1、什么是LitJSON?

它是一个第三方库,用于处理惩罚Jso的序列化和反序列化,LitJson是c#编写的,体积小、速度快、易于使用,它可以很容易的嵌入到我们的代码中,只必要将LitJson代码拷贝到工程中即可
2、获取LitJson

官网

https://litjson.net/
GitHub

https://github.com/LitJSON/litjson

导入LitJson进项目

留代码即可

3、注意



  • 相对于JsonUtility不必要加特性
  • 不能序列化私有变量
  • 支持字典类型,字典的键发起都是字符串因为Json的特点Json中的键会加上双引号
  • 必要导入LitJson和引用LitJson定名空间
  • LitJson可以准确的保存null类型
  • LitJson无法序列化vector Color Quaternion等数据
  • 类布局必要无参构造函数,否则反序列化时报错
  • 字典固然支持,但是键为数值反序列化时会有问题,所以字典的键必要严格使用字符串类型才对
4、案例

界说一些不同类型的数据

  1. public class Data{
  2.     public string name = "小明";
  3.     public string name2 = null;
  4.     public int age = 12;
  5.     public float height = 1.85f;
  6.     public int[] ids = {1, 2, 3};
  7.     public List<int> list = new List<int>{11, 22, 33};
  8.     public Dictionary<string, string> strDic = new Dictionary<string, string>{{"key1", "内容1"}, {"key2", "内容2"}, {"key3", "内容3"}};
  9.     public Son son2 = new Son("子数据", 1);
  10.     public List<Son> listSon = new List<Son>{new Son("数据1", 1), new Son("子数据2", 2)};
  11.        
  12.         public override string ToString()
  13.     {
  14.         string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
  15.                         $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
  16.                         $"StrDic: {string.Join(", ", strDic)}\n" +
  17.                         $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n";
  18.         return result;
  19.     }
  20. }
  21. public class Son{
  22.     public string name;
  23.     public int age;
  24.        
  25.         //注意不能省略,下面会说原因
  26.         public Son() { }
  27.        
  28.     public Son(string name, int age){
  29.         this.name = name;
  30.         this.age = age;
  31.     }
  32. }
复制代码
使用LitJson序列化

  1. Data data = new Data();
  2. string jsonData = JsonMapper.ToJson(data);
  3. File.WriteAllText(Application.persistentDataPath + "/Test.json", jsonData);
复制代码
存储结果

使用LitJson举行反序列化

  1. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  2. Data data2 = JsonMapper.ToObject<Data>(jsonStr);
  3. print(data2.ToString());
复制代码
打印结果

再次强调


  • 类布局必要无参构造函数,否则反序列化时报错,也就是我前面public Son() { }不能省略的原因
  • 字典固然支持,但是键为数值反序列化时会有问题,所以字典的键必要严格使用字符串类型才对
5、LitJson能直接将数据反序列化为数据集合

比如我们想读取这样的数组json数据

界说数据
  1. public class Data1
  2. {
  3.     public string name;
  4.     public int age;
  5.    
  6.     public override string ToString()
  7.     {
  8.         string result = $"name: {name}, age: {age}";
  9.         return result;
  10.     }
  11. }
复制代码
读取
  1. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  2. List<Data1> data2 = JsonMapper.ToObject<List<Data1>>(jsonStr);
  3. print(data2[0].ToString());
复制代码
结果

6、总结



  • LitJson提供的序列化反序列化方法JsonMapper.ToJson和JsonMapper.ToObject<>
  • LitJson无需加特性
  • LitJson不支持私有变量
  • LitJson支持字典序列化反序列化
  • 字典固然支持,但是键为数值反序列化时会有问题,所以字典的键必要严格使用字符串类型才对
  • LitJson可以直接将数据反序列化为数据集合
  • LitJson反序列化时自界说类型必要无参构造
  • Json文档编码格式必须是UTF-8
  • 使用LitJson必要导入LitJson和引用LitJson定名空间
  • LitJson可以准确的保存null类型
  • LitJson无法序列化vector Color Quaternion等数据

四、Newtonsoft

1、什么是Newtonsoft?

Newtonsoft.Json 是一个非常盛行的 C# JSON 序列化和反序列化库,它可以方便地将 C# 对象转换为 JSON 格式,或者将 JSON 数据分析为 C# 对象。
相比其他的JSON工具,Newtonsoft.Json支持绝大多数平台。有着最丰富的功能和API,不浮夸的说,可以支持所有的数据布局类型,包罗你自界说的数据布局类型,且序列化反序列化过程可定制。
与之相对的,Newtonsoft.Json的包体也会稍大,如果对包体的大小不追求极限的话,可以说Newtonsoft.Json就是你在Unity开发中使用Json的不二之选。
2、获取Newtonsoft

直接在unity安装插件支持即可

如果安装了还是无法使用,记得重启unity再试即可
3、注意



  • 使用Newtonsoft必要引入Newtonsoft.Json定名空间
  • Newtonsoft无需加特性
  • Newtonsoft不支持私有变量
  • Newtonsoft支持键为数值或者字符串的字典序列化反序列化
  • Newtonsoft可以直接将数据反序列化为数据集合
  • Newtonsoft可以准确的保存null类型
  • Newtonsoft可以序列化vector Color Quaternion等数据,不过必要额外配JsonSerializerSettings参数
4、案例

界说一些不同类型的数据

  1. public class Data
  2. {
  3.     public string name = "小明";
  4.     public string name2 = null;
  5.     public int age = 12;
  6.     public float height = 1.85f;
  7.     public int[] ids = { 1, 2, 3 };
  8.     public List<int> list = new List<int> { 11, 22, 33 };
  9.     public Dictionary<int, string> intDic = new Dictionary<int, string> { { 1, "内容1" }, { 2, "内容2" }, { 3, "内容3" } };
  10.     public Dictionary<string, string> strDic = new Dictionary<string, string> { { "key1", "内容1" }, { "key2", "内容2" }, { "key3", "内容3" } };
  11.     public Son son2 = new Son("子数据", 1);
  12.     public List<Son> listSon = new List<Son> { new Son("数据1", 1), new Son("子数据2", 2) };
  13.     public Vector3 vector3 = new Vector3(1, 2, 1);
  14.     public Color color = Color.red;
  15.     public Quaternion rotation = Quaternion.Euler(0f, 90f, 0f);
  16.     public override string ToString()
  17.     {
  18.         string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
  19.                         $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
  20.                         $"IntDic: {string.Join(", ", intDic)}, StrDic: {string.Join(", ", strDic)}\n" +
  21.                         $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n"+
  22.                         $"vector3: {vector3}, color: {color}, rotation: {rotation}";
  23.         return result;
  24.     }
  25. }
  26. public class Son
  27. {
  28.     public string name;
  29.     public int age;
  30.     public Son(string name, int age)
  31.     {
  32.         this.name = name;
  33.         this.age = age;
  34.     }
  35. }
复制代码
使用Newtonsoft序列化

  1. Data data = new Data();
  2. var settings = new JsonSerializerSettings
  3. {
  4.     TypeNameHandling = TypeNameHandling.Auto,
  5.     ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
  6.     Formatting = Formatting.Indented,
  7. };
  8. string jsonData = JsonConvert.SerializeObject(data, settings);
  9. File.WriteAllText(Application.persistentDataPath + "/Test.json", jsonData);
复制代码
JsonSerializerSettings 对象先容
TypeNameHandling = TypeNameHandling.Auto:


  • 这个设置告诉 JSON 序列化器在序列化对象时,主动将类型信息包罗在 JSON 数据中。这样,当你反序列化该 JSON 字符串时,可以恢复对象的确切类型。
  • Auto 选项表示只会在对象中包罗详细类型信息,如果碰到继续自某个基类的类型时,会主动添加基类的类型信息。其他选项还包罗 None(不包罗类型信息)和 All(包罗所有类型信息)。
ReferenceLoopHandling = ReferenceLoopHandling.Ignore:


  • 这个设置指定在序列化时碰到引用循环(例如,一个对象的属性又引用了自己或其父对象时)应该怎样处理惩罚。设置为 Ignore 时,序列化器会跳过这些循环引用。
  • 这种情况通常出现在包罗相互引用的复杂对象布局中,比如两个对象相互引用对方。
Formatting = Formatting.Indented:


  • 设置序列化的 JSON 字符串格式。Indented 会让输出的 JSON 格式化成易读的缩进格式(即,每层嵌套都会有缩进)。这在调试时非常有用,因为它使得 JSON 内容更加清楚。
结果,因为前面设置了Formatting = Formatting.Indented,存储的内容格式就是这样,我并没有举行美化

使用Newtonsoft举行反序列化

  1. var settings = new JsonSerializerSettings
  2. {
  3.     TypeNameHandling = TypeNameHandling.Auto,
  4.     ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
  5.     Formatting = Formatting.Indented,
  6. };
  7. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  8. Data data2 = JsonConvert.DeserializeObject<Data>(jsonStr, settings);
  9. print(data2.ToString());
复制代码
打印结果

5、Newtonsoft能直接将数据反序列化为数据集合

比如我们想读取这样的数组json数据

界说数据
  1. public class Data1
  2. {
  3.     public string name;
  4.     public int age;
  5.    
  6.     public override string ToString()
  7.     {
  8.         string result = $"name: {name}, age: {age}";
  9.         return result;
  10.     }
  11. }
复制代码
读取
  1. string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
  2. List<Data1> data2 = JsonConvert.DeserializeObject<List<Data1>>(jsonStr);
  3. print(data2[0].ToString());
复制代码
结果

6、总结



  • Newtonsoft提供的序列化反序列化方法JsonConvert.SerializeObject和JsonConvert.DeserializeObject<>
  • 使用Newtonsoft必要引入Newtonsoft.Json定名空间
  • Newtonsoft无需加特性
  • Newtonsoft不支持私有变量
  • Newtonsoft支持键为数值或者字符串的字典序列化反序列化
  • Newtonsoft可以直接将数据反序列化为数据集合
  • Json文档编码格式必须是UTF-8
  • Newtonsoft可以准确的保存null类型
  • Newtonsoft可以序列化vector Color Quaternion等数据,不过必要额外配JsonSerializerSettings参数
  • Newtonsoft还可以对Json格式美化,存储成易读的缩进格式

五、结论

结论毋庸置疑了,Newtonsoft集合了JsonUtlity和LitJSON的所有优点,又巧妙避开了所有缺点,而且它还有自己的优点,比如对Json格式美化。如果肯定要说缺点的话,那大概就是Newtonsoft的包体比JsonUtlity和LitJSON大一点,不过也仅仅是大一点而已。
完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不停创作的最大动力。固然如果你发现了文章中存在错误或者有更好的办理方法,也欢迎评论私信告诉我哦!
好了,我是向宇,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的履历总是会给我很多帮助和启发!如果你碰到任何问题,也欢迎你评论私信或者加群找我, 固然有些问题我也不肯定会,但是我会查阅各方资料,争取给出最好的发起,希望可以帮助更多想学编程的人,共勉~


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表