前言
本篇为学习总结性质的文章,若发现任何问题或错误,欢迎在评论区指出。
如果本文对您有一定帮助,也欢迎点赞、收藏、关注。
目录
前置知识
Json序列化、反序列化的基本方法
本文我们会围绕JsonUtility(Unity自带的用于解析Json的公共类)和LitJson(解析Json的第三方库)来编写一个简单的Json管理器工具。
如果不熟悉JsonUtility和LitJson,可以看我的这篇文章:Unity学习笔记:数据持久化之Json(一)基础 ,或去对应的官方文档详细了解。
Unity中的特殊文件夹与路径
本文我们需要用到流文件夹和持久数据文件夹。
StreamingAssets流文件夹
- 需要在Assets下手动创建,名为“StreamingAssets”
- 通过Application.streamingAssetsPath点出
- 不同于Resources,打包后不会被压缩加密
- 安卓等移动平台只读,PC平台可读可写
- 通常放入需要动态加载的初始资源(二进制文件为主)
PersistentDataPath持久数据文件夹
- 不需要手动创建,在不同平台其路径不同(通常在用户相关文件夹)
- 通过Application.persistentDataPath点出
- 所有平台都可读可写
- 通常用于放置动态下载或创建的文件
Unity中的文件读写
Unity中的File类可用于对单个文件进行操作,此次我们会用到以下三个方法:
//引用:
using System.IO;
//1.将字符串内容写入指定路径的文件中:
File.WriteAllText(string path, string contents); //分别传入路径和内容
//2.读取指定路径文件的内容,返回String
File.ReadAllText(string path); //传入路径
//3.判断指定路径文件是否存在,返回bool值
File.Exists(string path); //传入待检查的文件路径
思路
方案枚举
我们会使用两种不同的序列化方法,以满足不同的需求。
所以我们首先可以先定义一个枚举,存放不同方案。这样在序列化和反序列化时额外传入所用的方案,就能满足不同需求。
public enum JsonType
{
JsonUtlity,
LitJson,
}
单例模式
作为一个工具类、数据管理类,我们可以想到令其为一个单例模式的类。
public class JsonMgr
{
//单例模式
private static JsonMgr instance = new JsonMgr();
public static JsonMgr Instance => instance;
private JsonMgr() { }
//序列化
//反序列化
}
当然也可以写个单例模式基类,方便包括JsonMgr在内的各种工具类或管理类继承,快速便捷地实现单例模式:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Singleton<T> where T:new()
{
private static T instance;
public static T GetInstance()
{
if (instance == null)
instance = new T();
return instance;
}
}
序列化
//序列化,传入对象、目标文件路径、方案
public void SaveData(object data, string fileName, JsonType type = JsonType.LitJson)
{
//确定存储路径
string path = Application.persistentDataPath + "/" + fileName + ".json";
//序列化 得到Json字符串
string jsonStr = "";
switch (type) //根据方案的不同进行转换
{
case JsonType.JsonUtlity:
jsonStr = JsonUtility.ToJson(data);
break;
case JsonType.LitJson:
jsonStr = JsonMapper.ToJson(data);
break;
}
//把序列化的Json字符串 存储到指定路径的文件中
File.WriteAllText(path, jsonStr);
}
反序列化
//反序列化,传入文件路径、方案,返回对应对象
public T LoadData<T>(string fileName, JsonType type = JsonType.LitJson) where T : new()
{
//确定从哪个路径读取:
//首先判断默认数据文件夹中是否有我们想要的数据
string path = Application.streamingAssetsPath + "/" + fileName + ".json";
//如果不存在默认文件,就从读写文件夹中去寻找
if(!File.Exists(path))
path = Application.persistentDataPath + "/" + fileName + ".json";
//如果读写文件夹中仍没有,那就返回一个默认对象
if (!File.Exists(path))
return new T();
//进行反序列化
string jsonStr = File.ReadAllText(path);
//数据对象
T data = default(T);
switch (type) //根据方案的不同进行转换
{
case JsonType.JsonUtlity:
data = JsonUtility.FromJson<T>(jsonStr);
break;
case JsonType.LitJson:
data = JsonMapper.ToObject<T>(jsonStr);
break;
}
return data;
}
源码
using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
/// <summary>
/// 方案枚举,还可后续添加
/// </summary>
public enum JsonType
{
JsonUtlity,
LitJson,
}
/// <summary>
/// Json数据管理类
/// </summary>
public class JsonMgr
{
//单例模式
private static JsonMgr instance = new JsonMgr();
public static JsonMgr Instance => instance;
private JsonMgr() { }
//序列化
public void SaveData(object data, string fileName, JsonType type = JsonType.LitJson)
{
//确定存储路径
string path = Application.persistentDataPath + "/" + fileName + ".json";
//序列化 得到Json字符串
string jsonStr = "";
switch (type) //根据方案的不同进行转换
{
case JsonType.JsonUtlity:
jsonStr = JsonUtility.ToJson(data);
break;
case JsonType.LitJson:
jsonStr = JsonMapper.ToJson(data);
break;
}
//把序列化的Json字符串,存储到指定路径的文件中
File.WriteAllText(path, jsonStr);
}
//反序列化
public T LoadData<T>(string fileName, JsonType type = JsonType.LitJson) where T : new()
{
//确定从哪个路径读取:
//首先判断默认数据文件夹中是否有我们想要的数据
string path = Application.streamingAssetsPath + "/" + fileName + ".json";
//如果不存在默认文件,就从读写文件夹中去寻找
if(!File.Exists(path))
path = Application.persistentDataPath + "/" + fileName + ".json";
//如果读写文件夹中仍没有,那就返回一个默认对象
if (!File.Exists(path))
return new T();
//进行反序列化
string jsonStr = File.ReadAllText(path);
//数据对象
T data = default(T);
switch (type) //根据方案的不同进行转换
{
case JsonType.JsonUtlity:
data = JsonUtility.FromJson<T>(jsonStr);
break;
case JsonType.LitJson:
data = JsonMapper.ToObject<T>(jsonStr);
break;
}
return data;
}
}
注意:因为使用了第三方库LitJson,所以打包时需要将LitJson核心代码一起打包。