泉缘泉 发表于 2025-1-6 08:35:05

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

前言

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://i-blog.csdnimg.cn/direct/561aa8b2262246fc92244bd338bc9026.png
其他: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序列化时看起来会有一些误差,但是读取着实不影响
[*]自界说类必要加上序列化特性
[*]想要序列化私有变量必要加上特性
[*]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);
   
    private int privateInt = 66;
   
    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;
    }
}


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数据存储的是默认值
https://i-blog.csdnimg.cn/direct/b649b879107742e0964abe6ce28915ca.png
使用JsonUtlity举行反序列化

string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
Data data2 = JsonUtility.FromJson<Data>(jsonStr);
print(data2.ToString());
打印结果,这里还是有打印出字典的原因是因为,字典数据没有读取到,所以输出了默认值
https://i-blog.csdnimg.cn/direct/1fd94eba49c74aa2a96f60f6d1c2b8b4.png
4、JsonUtility不能直接将数据反序列化为数据集合

比如我们想读取这样的数组json数据
https://i-blog.csdnimg.cn/direct/3341ed673f7b4438bef023b1ca37fadf.png
界说数据
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.ToString());
结果直接会报错
https://i-blog.csdnimg.cn/direct/d01d272a117946e6aadcc30d9c9548d8.png
5、总结



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

1、什么是LitJSON?

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

官网

https://litjson.net/
GitHub

https://github.com/LitJSON/litjson
https://i-blog.csdnimg.cn/direct/d3ffc7e815bf44c9a927dc63e9d2448e.png
导入LitJson进项目
https://i-blog.csdnimg.cn/direct/e8354c406436418d8fb51cdf992c084c.png
留代码即可
https://i-blog.csdnimg.cn/direct/8ac00871515846be85fe333b79bf116c.png
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);
存储结果
https://i-blog.csdnimg.cn/direct/c0a309b6ac534cf3bd84c7dd03e80a35.png
使用LitJson举行反序列化

string jsonStr = File.ReadAllText(Application.persistentDataPath + "/Test.json");
Data data2 = JsonMapper.ToObject<Data>(jsonStr);
print(data2.ToString());
打印结果
https://i-blog.csdnimg.cn/direct/a9b07dbb28d4416eb17fc85b00e70798.png
再次强调


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

比如我们想读取这样的数组json数据
https://i-blog.csdnimg.cn/direct/3341ed673f7b4438bef023b1ca37fadf.png
界说数据
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.ToString());
结果
https://i-blog.csdnimg.cn/direct/9401b6bfd6e34d2a82fa5678cb10792c.png
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安装插件支持即可
https://i-blog.csdnimg.cn/direct/df5ffa920ca44cda853c4b22405a65bb.png
如果安装了还是无法使用,记得重启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,存储的内容格式就是这样,我并没有举行美化
https://i-blog.csdnimg.cn/direct/ca81cae0666a42209b6136ee5d6b537f.png
使用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());
打印结果
https://i-blog.csdnimg.cn/direct/3e0ac2702b694d2e90349febea56ab99.png
5、Newtonsoft能直接将数据反序列化为数据集合

比如我们想读取这样的数组json数据
https://i-blog.csdnimg.cn/direct/3341ed673f7b4438bef023b1ca37fadf.png
界说数据
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.ToString());
结果
https://i-blog.csdnimg.cn/direct/0e8d74e26aa8433a8e7dd45aa1ed6b55.png
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
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的履历总是会给我很多帮助和启发!如果你碰到任何问题,也欢迎你评论私信或者加群找我, 固然有些问题我也不肯定会,但是我会查阅各方资料,争取给出最好的发起,希望可以帮助更多想学编程的人,共勉~
https://img-blog.csdnimg.cn/direct/4a8db123e30a4f86a0a183c963769343.gif#pic_center

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【保举100个unity插件之37】unity使用三种方式实现对Json数据的序列化和反