前言
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会为我们分配不同的长期化数据路径,这样可以确保应用程序在不同平台上都能正确保存和访问
- //设置存档文件路径
- savePath = Path.Combine(Application.persistentDataPath, "saveData.json");
复制代码 不同平台存储的路径不一样,我们可以打印savePath查看自己的存储路径
比如我PC上的就是
其他:https://blog.csdn.net/qq_36303853/article/details/129688513
2、将字符串存入文件中
File.WriteAllText()将字符串写入到指定路径文件中
- 第一个参数填写的是存储的路径
- 第二个参数填写的是存储的字符串内容
- 注意:第一个参数必须是存在的文件路径如果没有对应文件夹会报错
- File.WriteAllText(Application.persistentDataPath + "/Test.json", "json文件");
复制代码 3、读取文件中的字符串内容
- 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、实例
界说一些不同类型的数据
- public class Data{
- public string name = "小明";
- public string name2 = null;
- public int age = 12;
- public float height = 1.85f;
- public int[] ids = {1, 2, 3};
- public List<int> list = new List<int>{11, 22, 33};
- public Dictionary<int, string> intDic = new Dictionary<int, string>{{1, "内容1"}, {2, "内容2"}, {3, "内容3"}};
- public Dictionary<string, string> strDic = new Dictionary<string, string>{{"key1", "内容1"}, {"key2", "内容2"}, {"key3", "内容3"}};
- public Son son2 = new Son("子数据", 1);
- public List<Son> listSon = new List<Son>{new Son("数据1", 1), new Son("子数据2", 2)};
- public Vector3 vector3 = new Vector3(1, 2, 1);
- public Color color = Color.red;
- public Quaternion rotation = Quaternion.Euler(0f, 90f, 0f);
- [SerializeField]
- private int privateInt = 66;
- [SerializeField]
- protected int protectedInt = 77;
- public override string ToString()
- {
- string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
- $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
- $"IntDic: {string.Join(", ", intDic)}, StrDic: {string.Join(", ", strDic)}\n" +
- $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n" +
- $"vector3: {vector3}, color: {color}, rotation: {rotation}\n" +
- $"privateInt: {privateInt}, protectedInt: {protectedInt}";
- return result;
- }
- }
- [System.Serializable]
- public class Son{
- public string name;
- public int age;
- public Son(string name, int age){
- this.name = name;
- this.age = age;
- }
- }
复制代码 使用JsonUtility.ToJson举行序列化
- Data data = new Data();
- string jsonData = JsonUtility.ToJson(data);
- File.WriteAllText(Application.persistentDataPath + "/Test.json", jsonData);
复制代码 存储结果
可以看到如前面所说,字典无法存储,float类型存储有些误差,null数据存储的是默认值
使用JsonUtlity举行反序列化
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- Data data2 = JsonUtility.FromJson<Data>(jsonStr);
- print(data2.ToString());
复制代码 打印结果,这里还是有打印出字典的原因是因为,字典数据没有读取到,所以输出了默认值
4、JsonUtility不能直接将数据反序列化为数据集合
比如我们想读取这样的数组json数据
界说数据
- public class Data1
- {
- public string name;
- public int age;
-
- public override string ToString()
- {
- string result = $"name: {name}, age: {age}";
- return result;
- }
- }
复制代码 读取
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- List<Data1> data2 = JsonUtility.FromJson<List<Data1>>(jsonStr);
- 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、案例
界说一些不同类型的数据
- public class Data{
- public string name = "小明";
- public string name2 = null;
- public int age = 12;
- public float height = 1.85f;
- public int[] ids = {1, 2, 3};
- public List<int> list = new List<int>{11, 22, 33};
- public Dictionary<string, string> strDic = new Dictionary<string, string>{{"key1", "内容1"}, {"key2", "内容2"}, {"key3", "内容3"}};
- public Son son2 = new Son("子数据", 1);
- public List<Son> listSon = new List<Son>{new Son("数据1", 1), new Son("子数据2", 2)};
-
- public override string ToString()
- {
- string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
- $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
- $"StrDic: {string.Join(", ", strDic)}\n" +
- $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n";
- return result;
- }
- }
- public class Son{
- public string name;
- public int age;
-
- //注意不能省略,下面会说原因
- public Son() { }
-
- public Son(string name, int age){
- this.name = name;
- this.age = age;
- }
- }
复制代码 使用LitJson序列化
- Data data = new Data();
- string jsonData = JsonMapper.ToJson(data);
- File.WriteAllText(Application.persistentDataPath + "/Test.json", jsonData);
复制代码 存储结果
使用LitJson举行反序列化
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- Data data2 = JsonMapper.ToObject<Data>(jsonStr);
- print(data2.ToString());
复制代码 打印结果
再次强调
- 类布局必要无参构造函数,否则反序列化时报错,也就是我前面public Son() { }不能省略的原因
- 字典固然支持,但是键为数值反序列化时会有问题,所以字典的键必要严格使用字符串类型才对
5、LitJson能直接将数据反序列化为数据集合
比如我们想读取这样的数组json数据
界说数据
- public class Data1
- {
- public string name;
- public int age;
-
- public override string ToString()
- {
- string result = $"name: {name}, age: {age}";
- return result;
- }
- }
复制代码 读取
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- List<Data1> data2 = JsonMapper.ToObject<List<Data1>>(jsonStr);
- 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、案例
界说一些不同类型的数据
- public class Data
- {
- public string name = "小明";
- public string name2 = null;
- public int age = 12;
- public float height = 1.85f;
- public int[] ids = { 1, 2, 3 };
- public List<int> list = new List<int> { 11, 22, 33 };
- public Dictionary<int, string> intDic = new Dictionary<int, string> { { 1, "内容1" }, { 2, "内容2" }, { 3, "内容3" } };
- public Dictionary<string, string> strDic = new Dictionary<string, string> { { "key1", "内容1" }, { "key2", "内容2" }, { "key3", "内容3" } };
- public Son son2 = new Son("子数据", 1);
- public List<Son> listSon = new List<Son> { new Son("数据1", 1), new Son("子数据2", 2) };
- public Vector3 vector3 = new Vector3(1, 2, 1);
- public Color color = Color.red;
- public Quaternion rotation = Quaternion.Euler(0f, 90f, 0f);
- public override string ToString()
- {
- string result = $"Name: {name}, Name2: {name2}, Age: {age}, Height: {height}, " +
- $"IDs: {string.Join(", ", ids)}, List: {string.Join(", ", list)}\n" +
- $"IntDic: {string.Join(", ", intDic)}, StrDic: {string.Join(", ", strDic)}\n" +
- $"Son2: {son2}, ListSon: {string.Join(", ", listSon)}\n"+
- $"vector3: {vector3}, color: {color}, rotation: {rotation}";
- return result;
- }
- }
- public class Son
- {
- public string name;
- public int age;
- public Son(string name, int age)
- {
- this.name = name;
- this.age = age;
- }
- }
复制代码 使用Newtonsoft序列化
- Data data = new Data();
- var settings = new JsonSerializerSettings
- {
- TypeNameHandling = TypeNameHandling.Auto,
- ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
- Formatting = Formatting.Indented,
- };
- string jsonData = JsonConvert.SerializeObject(data, settings);
- 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举行反序列化
- var settings = new JsonSerializerSettings
- {
- TypeNameHandling = TypeNameHandling.Auto,
- ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
- Formatting = Formatting.Indented,
- };
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- Data data2 = JsonConvert.DeserializeObject<Data>(jsonStr, settings);
- print(data2.ToString());
复制代码 打印结果
5、Newtonsoft能直接将数据反序列化为数据集合
比如我们想读取这样的数组json数据
界说数据
- public class Data1
- {
- public string name;
- public int age;
-
- public override string ToString()
- {
- string result = $"name: {name}, age: {age}";
- return result;
- }
- }
复制代码 读取
- string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
- List<Data1> data2 = JsonConvert.DeserializeObject<List<Data1>>(jsonStr);
- 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企服之家,中国第一个企服评测及商务社交产业平台。 |