JSON简介
JSON概述
JSON的全称为:JavaScript对象简谱(JavaScript Object Notation)
JSON是国际通用的一种轻量级的数据交换格式,主要用于在网络通讯中用于传输数据,或用于本地数据存储和读取。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON结构
JSON的注释:
JSON的注释方式和C#一样:
“//”:为单行注释。
“/**/”:为多行注释。
JSON的语法规则:
符号含义:
大括号 {} —— 对象
中括号 [] —— 数组
冒号 : —— 键值对对应关系,左侧为键右侧为值。
逗号 , —— 数据分割符
双引号 “” —— 键名/字符串
键值对表示:
“键名” : 值内容
JSON中的值类型:
数字,数组,布尔值,字符串,对象,null
JSON结构练习
{
//string类型数据
"name" : "tian",
//int类型
"atk" : 100,
//int类型
"def" : 100,
//float类型
"moveSpeed" : 10.0,
//float类型
"roundSpeed" : 10.0,
//类类型
"weapon" : {
"id" : 1,
"num" : 10
},
//int数组类型
"listInt" : [1,2,3,4],
//类数组类型
"itemList" : [
{"id" : 1, "num" : 10},
{"id" : 2, "num" : 10},
{"id" : 3, "num" : 10}
],
//字典类型
"itemDic" : {
"1" : {"id" : 1, "num" : 10},
"2" : {"id" : 2, "num" : 10},
"3" : {"id" : 3, "num" : 10}
},
//字典类型
"itemDic2" : {
"str1" : {"id" : 1, "num" : 10},
"str2" : {"id" : 2, "num" : 10},
"str3" : {"id" : 3, "num" : 10}
}
}
这里需要注意的是,字典存储为json形式不可以使用数组[]存储,而应当使用对象{}存储,且存储时字典的键必须存储为字符串。
配置JSON文档时的注意事项
-
如果数据表示对象,那么最外层应当是一个大括号。
-
JSON文件中一定都是键值对的形式存储数据。
-
JSON中的键值一定是字符串格式的。
-
键值对之间需要使用数据分割符","。
-
JSON中数组需要使用"[]"包裹。
-
JSON中对象需要使用"{}"包裹。
JsonUtlity
JsonUtility是Unity自带的用于解析Json数据的公共类,它可以对对象序列化为Json字符串,也可以将Jon字符串反序列化成类对象。
JsonUtility序列化
//将对象内容转换为Json字符串
string jsonWord = JsonUtility.ToJson(playerInfo);
//将Json字符串写入文件
File.WriteAllText(Application.streamingAssetsPath + "/jsonUtility.json", jsonWord);
JsonUtility反序列化
//将文件中的数据读取出来
string jsonPer = File.ReadAllText(Application.streamingAssetsPath + "/jsonUtility.json");
//将Json字符串转换为对象
PlayerInfo playerInfo2 = JsonUtility.FromJson<PlayerInfo>(jsonPer);
使用JsonUtility的注意事项
- 对于自定义类对象,我们需要加[Serializable]特性才可以被序列化。
- 对于private和protected访问的字段我们需要加[SerializeField]特性才可以被序列化。
- JsonUtility不能序列化字典类型。
- JsonUtility不能直接读取数组Json。
- JsonUtility读取的Json文件的编码格式必须是UTF-8。
LitJson
LitJson是一个第三方库,用于处理Json的序列化和反序列化,LitJson是使用C#编写的,体积小,速度快,易于使用,我们只需要将官网下载的代码拷贝到我们的工程中或者导入LitJson的DLL文件即可使用。
LitJson序列化
//将对象内容转换为Json字符串
string jsonFormat = JsonMapper.ToJson(playerInfo);
//将Json字符串写入文件
File.WriteAllText(Application.streamingAssetsPath + "/LitJson.json", jsonFormat);
LitJson反序列化
//将文件中的数据读取出来
string jsonWord = File.ReadAllText(Application.streamingAssetsPath + "/LitJson.json");
//将Json字符串转换为对象
PlayerInfo2 playerInfo2 = JsonMapper.ToObject<PlayerInfo2>(jsonWord);
使用LitJson的注意事项
- LitJson反序列化时,需要目标对象有无参构造函数。
- LitJson不需要使用特性就可以进行序列化和反序列化。
- LitJson不能序列化私有字段和保护字段。
- LitJson可以直接序列化字典。但是序列化的字典建议其键为string类型。
- LitJson可以直接序列化数组Json。
- LitJson读取的Json文件的编码格式必须是UTF-8。
Json管理类的简单实现
BaseSingleton:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
Editor:
Version:
The last time for modification:
Time for Creation:
*/
namespace CsharpBaseModule.Singleton
{
/// <summary>
/// 基础单例类,线程不安全
/// </summary>
public class BaseSingleton<T> where T : new()
{
private static T _instance;
public static T GetInstance
{
get
{
if (_instance == null)
{
_instance = new T();
}
return _instance;
}
}
}
}
using System;
using System.IO;
using CsharpBaseModule.Singleton;
using LitJson;
using UnityEngine;
public enum JsonType
{
LitJson,
JsonUtility,
}
public class JsonManager : BaseSingleton<JsonManager>
{
public void SaveData(object data, string filePath, JsonType type = JsonType.LitJson)
{
if (!File.Exists(filePath))
{
Debug.Log($"当前路径不存在请重新检查路径:{filePath}");
return;
}
string jsonContent = "";
switch (type)
{
case JsonType.JsonUtility:
jsonContent = JsonUtility.ToJson(data);
break;
case JsonType.LitJson:
jsonContent = JsonMapper.ToJson(data);
break;
}
File.WriteAllText(filePath, jsonContent);
}
public T LoadData<T>(string filePath, JsonType type = JsonType.LitJson) where T : new()
{
if (!File.Exists(filePath))
{
Debug.Log($"当前路径不存在请重新检查路径:{filePath}");
return default;
}
T data;
switch (type)
{
case JsonType.LitJson:
data = JsonMapper.ToObject<T>(filePath);
break;
case JsonType.JsonUtility:
data = JsonUtility.FromJson<T>(filePath);
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
return data;
}
}