文章目录

  • JSON概念:
  • JSON结构:
  • JSON优势:
  • 与JavaScript的关系:
  • Unity方法:
  • 使用JsonUtility
    • Json存储
    • Json加载:
    • 注意事项:
  • 完整代码参考:
  • 使用LitJson:
    • 存储方法:
    • 读取方法
    • 注意事项

JSON概念:

JSON(JavaScript Object Notation)一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。JSON采用兼容性很高的、完全独立于语言文本格式,同时也具备类似于C语言的习惯体系的行为。这些特性使JSON成为理想的数据交换语言。

JSON结构:

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

JSON优势:

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

与JavaScript的关系:

JavaScript为编程语言,Json是数据格式/语法。JSON独立于语言而存在,任何站在语言的角度及对象层面对他的解释都是有局限性或者是错误的。

Unity方法:

Unity 5.3之后自带了JsonUtility类处理Json数据 ,JsonUtility比其他Json库更快,常用的还有.Net库的Json.Net与LitJson, JsonUtility很快且GC很少。

FileStream vs StreamWriter vs StreamReader:

由于FileStream类读取的是字节数组,也就导致了它适合读取的是二进制文件 。

我们对文本的读写一般使用StreamReader和StreamWriter,因为不同的文本有不同的编码格式,这个StreamReader和和StreamWriter会帮我们自动处理,不需要关心文本文件的编码是什么。

使用JsonUtility

JsonUtility对List和Dictionary的序列化,List被类封装后可以序列化,Dictionary是将Key和Value分开存到两个List进行的序列化
https://blog.csdn.net/truck_truck/article/details/78292390
使用步骤:

Json存储

1先创建一个文件,2然后将数据转为Json字符串,3将字符串写入文件,4关闭文件

public void SaveByJosn(){StreamWriter streamWriter = new StreamWriter("C:/Users/17641/Desktop" + "/date.txt");//放在桌面便于观察,建议放在Application.dataPathStreamWriter streamWriter2 = new StreamWriter("C:/Users/17641/Desktop" + "/dateDic.txt");//存放字典的文件,与普通数据分开存放,带字典的数据和普通数据存一起会解析失败Save save = initDate();//初始化数据string JsonString = JsonUtility.ToJson(save);//存储普通数据 int float string List(里面不能放字典)streamWriter.Write(JsonString);string JsonDic = JsonUtility.ToJson(new Serialization<string, int>(save.h));//存储字典streamWriter2.Write(JsonDic);//foreach (var item in save.c)//{//    string JsonListDic = JsonUtility.ToJson(new Serialization<int, string>(item));//存储列表(里面放字典),无法读取,可以存//    streamWriter2.Write(JsonListDic);//}streamWriter.Close();streamWriter2.Close();}

字典的存放:写一个泛型类,将字典拆的Key和Value拆分成两个List进行存放

/// <summary>
/// 对字典的序列化,使用list进行存储字典的数据
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
[Serializable]
public class Serialization<TKey, TValue> : ISerializationCallbackReceiver
{[SerializeField]List<TKey> keys;//存放Key的列表[SerializeField]List<TValue> values;//存放Value的列表Dictionary<TKey, TValue> target;//目标字典public Dictionary<TKey, TValue> ToDictionary() { return target; }public Serialization(Dictionary<TKey, TValue> target){this.target = target;}public void OnBeforeSerialize() //序列化之前进行List拆分{keys = new List<TKey>(target.Keys);values = new List<TValue>(target.Values);}public void OnAfterDeserialize()//反序列化之后进行字典的组合{var count = Math.Min(keys.Count, values.Count);target = new Dictionary<TKey, TValue>(count);for (var i = 0; i < count; ++i){target.Add(keys[i], values[i]);}}
}

Json加载:

    /// <summary>/// 需要一个对应的结构体来接收,此处为Save/// </summary>public void LoadByJson(){Save save = new Save();if (File.Exists("C:/Users/17641/Desktop" + "/date.txt")){StreamReader reader = new StreamReader("C:/Users/17641/Desktop" + "/date.txt");string JsonString = reader.ReadToEnd();reader.Close();//从文件得到字符串后关闭文件save = JsonUtility.FromJson<Save>(JsonString);//对字符串进行拆分赋值,反序列化,读取非字典的数据StreamReader reader2 = new StreamReader("C:/Users/17641/Desktop" + "/dateDic.txt");string JsonString2 = reader2.ReadToEnd();reader2.Close();//save.c.Add(JsonUtility.FromJson<Serialization<int, string>>(JsonString2).ToDictionary());//读取带字典的列表,读取失败save.h = JsonUtility.FromJson<Serialization<string, int>>(JsonString2).ToDictionary();//读取字典的数据,Save类含有字典和非字典的数据,所以分开存放,分开读取}else{Debug.Log("No File");return;}Debug.Log(save.a);Debug.Log(save.b);//Debug.Log(save.c[0][0]);//对列表里面装字典,无法读取//Debug.Log(save.c[0][1]);//Debug.Log(save.c[1][2]);Debug.Log(save.g[3]);//列表Debug.Log(save.h["Attack10"]);//字典}
}

注意事项:

如果字典和普通数据(int float string List)放在一起存,Json会解析失败:

用校验工具试一下:

分开存放,可以读取成功

如果用字典装列表,再存放,会解析失败,所以装载字典的Json文件要纯粹,不能用列表包起来(数组没试过)

完整代码参考:

using System.Collections.Generic;
using System.IO;
using UnityEngine;//需要序列化存储的类型Save,内含字典和非字典的数据
[SerializeField]
public class Save : ISerializationCallbackReceiver
{public int a;public string b;public List<Dictionary<int, string>> c = new List<Dictionary<int, string>>();public float f;public List<string> Tkey;public List<float> Tvalue;public List<string> g = new List<string>();public Dictionary<string, int> h = new Dictionary<string, int>();public void OnAfterDeserialize(){Debug.Log("反序列化");}public void OnBeforeSerialize(){Debug.Log("开始系列化");}
}/// <summary>
/// 对字典的序列化,使用list进行存储字典的数据
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
[Serializable]
public class Serialization<TKey, TValue> : ISerializationCallbackReceiver
{[SerializeField]List<TKey> keys;[SerializeField]List<TValue> values;Dictionary<TKey, TValue> target;public Dictionary<TKey, TValue> ToDictionary() { return target; }public Serialization(Dictionary<TKey, TValue> target){this.target = target;}public void OnBeforeSerialize(){keys = new List<TKey>(target.Keys);values = new List<TValue>(target.Values);}public void OnAfterDeserialize(){var count = Math.Min(keys.Count, values.Count);target = new Dictionary<TKey, TValue>(count);for (var i = 0; i < count; ++i){target.Add(keys[i], values[i]);}}
}
//要在Unity中使用,在Star方法中调用一次
public class JsonTest : MonoBehaviour
{public static Dictionary<int, string> d = new Dictionary<int, string>();public static Dictionary<int, string> e = new Dictionary<int, string>();public static List<string> L = new List<string>();private void Start(){if (File.Exists("C:/Users/17641/Desktop" + "/date.txt")){Debug.Log("There are files!");}else{Debug.Log("No File");}SaveByJosn();LoadByJson();if (File.Exists("C:/Users/17641/Desktop" + "/date.txt")){Debug.Log("Save Sucess!");}else{Debug.Log("No File");}}//初始化数据public static Save initDate(){Save save = new Save();save.a = 18;save.b = "Hello Save";save.f = 0.98765f;d.Add(0, "这是一个键值为0的字典的内容");d.Add(1, "This is the contents of a dictionary with a key value of 1");e.Add(2, "@#$%^&*()");save.c.Add(d);save.c.Add(e);//列表带字典,存了两个字典(d,e)的列表L.Add("gggggggggg");//列表L.Add("asdasd");L.Add("098765432");L.Add("*&^^%%$%");save.g = L;save.h.Add("Attack1", 123);//字典save.h.Add("Attack2", 1234);save.h.Add("Attack3", 1232);save.h.Add("Attack4", 1223);save.h.Add("Attack10", 1233);save.h.Add("Attack15", 1243);return save;}public void SaveByJosn(){StreamWriter streamWriter = new StreamWriter("C:/Users/17641/Desktop" + "/date.txt");//放在桌面便于观察,建议放在Application.dataPathStreamWriter streamWriter2 = new StreamWriter("C:/Users/17641/Desktop" + "/dateDic.txt");//存放字典,分开存放,带字典的数据和普通数据存一起会解析失败Save save = initDate();//初始化数据string JsonString = JsonUtility.ToJson(save);//存储普通数据 int float string List(里面不能放字典)streamWriter.Write(JsonString);string JsonDic = JsonUtility.ToJson(new Serialization<string, int>(save.h));//存储字典streamWriter2.Write(JsonDic);//foreach (var item in save.c)//{//    string JsonListDic = JsonUtility.ToJson(new Serialization<int, string>(item));//存储列表(里面放字典)//    streamWriter2.Write(JsonListDic);//}streamWriter.Close();streamWriter2.Close();}/// <summary>/// 需要一个对应的结构体来接收,此处为Save/// </summary>public void LoadByJson(){Save save = new Save();if (File.Exists("C:/Users/17641/Desktop" + "/date.txt")){StreamReader reader = new StreamReader("C:/Users/17641/Desktop" + "/date.txt");string JsonString = reader.ReadToEnd();reader.Close();//从文件得到字符串save = JsonUtility.FromJson<Save>(JsonString);//对字符串进行拆分赋值,反序列化,读取非字典的数据StreamReader reader2 = new StreamReader("C:/Users/17641/Desktop" + "/dateDic.txt");string JsonString2 = reader2.ReadToEnd();//save.c.Add(JsonUtility.FromJson<Serialization<int, string>>(JsonString2).ToDictionary());//读取带字典的列表save.h = JsonUtility.FromJson<Serialization<string, int>>(JsonString2).ToDictionary();//读取字典}else{Debug.Log("No File");return;}Debug.Log(save.a);Debug.Log(save.b);//Debug.Log(save.c[0][0]);//对列表里面装字典//Debug.Log(save.c[0][1]);//Debug.Log(save.c[1][2]);Debug.Log(save.g[3]);//列表Debug.Log(save.h["Attack10"]);//字典}
}

使用LitJson:

存储方法:

1.建立存储类型,
2.对存储类型进行赋值,
3.使用string JsonStr = JsonMapper.ToJson(LitData);转成Json字符串,
4.使用File.WriteAllText(“C:/Users/17641/Desktop” + “/dateLit.txt”, JsonStr); 存储

例:

public class LitJsonData
{public int intLit;public string strLit;public List<string> ListLit= new List<string>();public Dictionary<string, int> DicList = new Dictionary<string, int>();public List<Dictionary<int, string>> ListDicLit = new List<Dictionary<int, string>>();
}
public void LitJsonSave(){//初始化数据LitJsonData LitData = new LitJsonData();LitData.intLit = 15;LitData.strLit = "这是一个用LitJson存储的字符串";L.Add("!@#!$$");L.Add("这是List的数据");LitData.ListLit = L;//LitData.DicList.Add("字典内容1", 15);带字典的内容可以存储成功,但是读取会失败//LitData.DicList.Add("字典内容2", 18);//d.Add(15, "List+Dic1");//d.Add(18, "List+Dic12");//e.Add(10, "List+Dic2");//LitData.ListDicLit.Add(d);//LitData.ListDicLit.Add(e);//初始化完毕//序列化string JsonStr = JsonMapper.ToJson(LitData);//LitJson不需要标记【SerializeField】//Debug.Log(JsonStr);File.WriteAllText("C:/Users/17641/Desktop" + "/dateLit.txt", JsonStr);//存到文件中,如果不存在会自动创建if (File.Exists("C:/Users/17641/Desktop" + "/dateDic.txt")){Debug.Log("JsonLit Save Sucess!");}}


可以看到保存成文件后,中文被转码

读取方法

得到Json字符串,使用JsonMapper.ToObject进行反序列化,并赋予结构体,之后即可使用

public void LitJsonLoad(){string JsonLitLoad = File.ReadAllText("C:/Users/17641/Desktop" + "/dateLit.txt");//可以使用try进行安全校验,读取Json字符串//用结构体接收 LitJsonDataLitJsonData LitDataLoad = new LitJsonData();LitDataLoad = JsonMapper.ToObject<LitJsonData>(JsonLitLoad);Debug.Log(LitDataLoad.strLit);//字符串Debug.Log(LitDataLoad.intLit);//整数Debug.Log(LitDataLoad.ListLit[0]);//列表 一号元素对应的内容  L.Add("!@#!$$");//Debug.Log(LitDataLoad.DicList["字典内容1"]);//字典,key为字典内容1对应的内容,带字典的内容可以存储成功,但是读取会失败//Debug.Log(LitDataLoad.ListDicLit[0][18]);//对应第一个字典,Key为18的内容,即  d.Add(18, "List+Dic12");}


**

注意事项

**:字典可以存储,但是无法读取,要对数据进行类似JsonUtility的改造

带字典的存储

带字典的读取:

读取失败

Unity数据持久化-Json相关推荐

  1. Unity数据持久化——Json

    1.Json是什么? 全称: JavaScript对象简谱((JavaScript Object Notation) Json是国际通用的一种轻量级的数据交换格式 主要在网络通讯中用于传输数据,或本地 ...

  2. Unity之数据持久化——Json

    1.Json是什么 JavaScript对象简谱(JavaScript Object Notation) json是国际通用的一种轻量级的数据交换格式,主要在网络通讯中用于传输数据,或本地数据存储和读 ...

  3. 【Unity数据持久化_Json】(二)Excel转Json

    一.在Excel表中配置游戏数据 创建一个Excel文件,填写游戏数据 二.将Excel表中配置的数据转为Json配置 1.网页搜索Excel转Json 如:https://www.bejson.co ...

  4. 【Unity数据持久化】Ixmllserializable接口的使用

    一.Ixmllserializable是什么? 是C#中的XmlSerializer中提供了可拓展内容 可以让一些无法被序列化和反序列化的特殊类能被序列化(如Dictionary) 让特殊类继承Ixm ...

  5. 数据持久化Xml与Json

    Unity中常用的序列化方式有三种,二进制序列化,xml,json 二进制序列化因为不能维护字段,通常用于图片,音频,视频等文件的传输 Xml相比Json有阅读直白的优势,通常用于配置表 Json效率 ...

  6. python变量持久化_Python 数据持久化:JSON

    Python 数据持久化:JSON 编程派微信号:codingpy 淡蓝色字体可以直接点击查看 上周更新的<Think Python 2e>第14章讲述了几种数据持久化的方式,包括dbm. ...

  7. 爬虫之scrapy框架的数据持久化存储/保存为scv,json文件

    文章目录 前情回顾 selenium+phantomjs/chrome/firefox execjs模块使用 今日笔记 scrapy框架 小试牛刀 猫眼电影案例 知识点汇总 数据持久化存储(MySQL ...

  8. Unity使用Newtonsoft.Json插件实现XML与JSON数据的互转

    文章目录 插件介绍 Unity中使用Newtonsoft.Json进行xml与json互转 搭建demo场景 编写脚本实现json与xml互转的方法 demo演示效果 demo源工程 关于Newton ...

  9. Unity数据读写与存档(2)Json:成为神笔马良

    在上一篇我们知道,通过引入适当的第三方库并编写代码,就可以在Unity内,从Excel表格中读取一些数据. 配置表的存在,的确可以帮助开发团队中没有编程基础的小伙伴管理游戏数据,或者将游戏的策划数据较 ...

最新文章

  1. webview Java与JS互调
  2. 将您的窗口最前端显示
  3. 紧随时代发展 安防消费也在悄然发生改变
  4. linux常用管理命令
  5. QT 中QPainter绘制文字、图片
  6. leetcode —— 866. 回文素数
  7. 在游戏设备上砸钱 其实小姐姐们更疯狂!
  8. IE6下兼容CSS属性min-height的解决办法
  9. STL 算法接口及用法说明 (二)
  10. RedisTemplate常用使用说明-opsForHash(3)
  11. PLC数据采集之协议转换桥接器
  12. can bus测试工具
  13. 光伏窗性能研究(3)——单层光伏窗节能性能研究
  14. 作业调度框架 Quartz 学习笔记(三) -- Cron表达式 (转载)
  15. ubuntu vscode use clang-format google style
  16. 空调房早餐三杯水 让你轻松获得七大类营养
  17. 研究型论文框架及阅读文献方法
  18. 记录一下NotImplementedError: Cannot convert a symbolic Tensor的解决办法
  19. matlab程序算天气,科学网-站点气温数据的积温计算(含Matlab程序实现)-朱永超的博文...
  20. Proteus C51仿真学习板0——KeilProteus

热门文章

  1. RFID反向不归零编码(NRZ)
  2. liquibase介绍与使用
  3. openmeetings(八)
  4. TCP FIN扫描探测原理
  5. 学习OpCode前言
  6. 第一周总结(2022.10.17~2022.10.22)
  7. 前方高能!githubjava开源项目
  8. EWSTM8系列教程06_工程节点选项配置(一)
  9. 给阿里云域名解析添加CAA记录,防止你的域名证书被劫持
  10. MySQL Galera 集群安装与配置详解