PS:查找了很多相关资料,自己整理了下,方便日后回顾及分享。文末也提供了相关文件
关于Litjson文件:
可以去官网下载一个文件包;.dll文件存在于 litjson-0.5.0-bin\litjson-0.5.0\bin目录。
Litjson官网下载链接:LitJSON download | SourceForge.net
**本文主要研究用LitJson实现对文件的增加和修改功能以及Newtonsoft.Json删除和查找数据**
项目中建议用key ,value的形式读写json,主要使用JsonMapper、JsonUtility、PlayerPref等
相关API:
JsonWriter JsonData.ToJson() JsonMapper.ToObject()
文件流读取以及创建:
FileStream StreamReader File.WriteAllBytes
正则表达式解决Json文件被转译后不能显示中文问题:
//传入待转换的Json字符串,取得转换后的Json数据写入文件中
string ParseJsonData(string json)
{
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
string targetJson = reg.Replace(json, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
return targetJson;
}
本文创建的Json格式如下
- 依次为简单Json -> JsonSimpleDemo1()
- JsonWriter创建数组Json -> JsonWriterDemo()
- 数组型Json -> CreatJsonArrayDemo4()
- 数组型Json(增加数据) -> CreatJsonArrayDemo3()新脚本增加了tag数据图5
- 带有tag数据 -> CreatJsonArrayDemo3() 增加了tag数据
代码模块:
本文下载的是Json.Net 9.0.1
下载地址:https://github.com/SaladLab/Json.Net.Unity3D/releases 文末提供Newtonsoft.Json.dll文件链接
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
using UnityEngine.UI;
using System.IO;
using UnityEditor;
using System.Text;
using System.Text.RegularExpressions;
using System;
using Newtonsoft.Json.Linq;//使用JObject
public class JsonTest : MonoBehaviour {
public const string mobilePathInAndroid = "/storage/emulated/0/Dowload/";//安卓手机Download目录
public string jsonConfig = "";
public string filepath;
JsonData jData;
void Start()
{
//Unity里Assets目录下(测试用)和安卓手机目录(可读写)
#if UNITY_ANDROID && !UNITY_EDITOR
filepath=mobilePathInAndroid+"lzl.json";
#elif UNITY_STANDLONE_WIN || UNITY_EDITOR
filepath = Application.dataPath + "/lzl.json";
#endif
//Unity里StreamingAssets读写
//打包APK后建议使用streamingAssets
#if UNITY_ANDROID && !UNITY_EDITOR
jsonConfig=Application.streamingAssetsPath + "/lzl.json";
#elif UNITY_STANDLONE_WIN || UNITY_EDITOR
jsonConfig = "file://" + Application.streamingAssetsPath + "/lzl.json";
#endif
}
//直接创建简易Json格式
void JsonSimpleDemo1()
{
JsonData data = new JsonData();
data["id"] = "0";
data["name"] = "lzl";
data["sex"] = 1;
string jsonStr = data.ToJson();
CreatJsonFile(jsonStr);
}
//直接创建数组型Json格式
void JsonSimpleArrayDemo1()
{
JsonData data = new JsonData();
data["id"] = "0";
data["name"] = "lzl";
data["sex"] = 1;
data["info"] = new JsonData() ;
data["info"]["math"] = 99;
data["info"]["chinese"] = 99;
data["info"]["eglish"] = 99;
data["info2"] = new JsonData();
data["info2"]["math"] = 99;
data["info2"]["chinese"] = 99;
data["info2"]["eglish"] = 99;
string jsonStr = data.ToJson();
CreatJsonFile(jsonStr);
}
//使用JsonWriter创建
void JsonWriterDemo()
{
JsonWriter writer = new JsonWriter();
writer.WriteObjectStart();
writer.WritePropertyName("Hero01");
writer.Write("李四");
writer.WritePropertyName("Hero01_Info");
writer.WriteObjectStart();
writer.WritePropertyName("lv");
writer.Write(99);
writer.WritePropertyName("job");
writer.Write("战士");
writer.WritePropertyName("exp");
writer.Write("999");
writer.WriteObjectEnd();
//单个信息存入很方便,多个信息建议用数组。参考CreatJsonArrayDemo3()
//下面为测试
writer.WritePropertyName("Hero02");
writer.Write("赵六");
writer.WritePropertyName("Hero02_Info");
writer.WriteObjectStart();
writer.WritePropertyName("lv");
writer.Write(99);
writer.WritePropertyName("job");
writer.Write("法师");
writer.WritePropertyName("exp");
writer.Write("999");
writer.WriteObjectEnd();
writer.WriteObjectEnd();
string jsonSr = writer.ToString();
string target = ParseJsonData(jsonSr);//转译中文显示问题
CreatJsonFile(target);
}
void CreatJsonFile(string jsonStr)
{
StringBuilder sb = new StringBuilder();
StreamWriter sw;
FileInfo info = new FileInfo(filepath);
if (!info.Exists)
{
sw = info.CreateText();
print("文件不存在,创建数据");
}
else
{
info.Delete();
print("文件已经存在,删除数据");
sw = info.CreateText();
}
sw.Write(jsonStr);
sw.Close();
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
JsonData ReadJsonData()
{
if (!File.Exists(filepath))
return null;
FileStream fs = new FileStream(filepath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
JsonData val = JsonMapper.ToObject(sr.ReadToEnd());
if (fs != null)
fs.Close();
if (sr != null)
sr.Close();
return val;
}
void AddNewData(string oldStr)
{
JsonData jd = ReadJsonData();
StringBuilder sb = new StringBuilder();
sb.Append(',');
JsonWriter jw = new JsonWriter(sb);
StreamWriter sw; //写入流
if (File.Exists(filepath))
{
print("文件已经存在,我们要添加数据");
sw = File.AppendText(filepath);
}
else
{
sw = File.CreateText(filepath);
print("创建文件成功,开始写入数据");
}
//在原Json数据中继续追加新的内容
jw.WriteObjectStart();
//先写入键,再写入值(以下是两组键值)
jw.WritePropertyName("new_name");
jw.Write("lin");
jw.WritePropertyName("count");
jw.Write("155");
jw.WriteObjectEnd();
// sb.Append(jw.ToString());
//通过流去写入数据
sw.Write(sb);
//关闭流
sw.Close();
//销毁流
sw.Dispose();
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
//创建数组型Json
void CreatJsonArrayDemo3()
{
//用户数据1
JsonData j1 = new JsonData();
j1["id"] =0;
j1["name"] = "Huawei";
j1["industry"] = "electronic";
j1["product"] = "mobile";
j1["tags"] = new JsonData();
string test = "1,2,3,5";//测试字符串
string[] tags = test.Split(',');
for (int i = 0; i < tags.Length; i++)
{
j1["tags"].Add(Int32.Parse(tags[i]));//所属标签
}
//用户数据2
JsonData j2 = new JsonData();
j2["id"] = 1;
j2["name"] = "Apple";
j2["industry"] = "electronic";
j2["product"] = "Iphone";
j2["tags"] = new JsonData();
string test2 = "2,6,3,5";//测试字符串
string[] tags2 = test2.Split(',');
for (int i = 0; i < tags2.Length; i++)
{
j2["tags"].Add(Int32.Parse(tags2[i]));//所属标签
}
//用户数据3
JsonData j3 = new JsonData();
j3["id"] = 2;
j3["name"] = "小米";
j3["industry"] = "electronic";
j3["product"] = "Xiaomi";
j3["tags"] = new JsonData();
string test3 = "1,4,3,7";//测试字符串
string[] tags3 = test3.Split(',');
for (int i = 0; i < tags3.Length; i++)
{
j3["tags"].Add(Int32.Parse(tags3[i]));//所属标签
}
//添加到数组中
JsonData Arr = new JsonData();
Arr.Add(j1);
Arr.Add(j2);
Arr.Add(j3);
//标题Info
JsonData data = new JsonData();
data["info"] = Arr;
string json = data.ToJson();
//转译Json中文
string s = ParseJsonData(json);
//创建方式1
CreatJsonFile(s);
#region//创建方式2
/*
if (File.Exists(filepath))
{
File.Delete(filepath);
Debug.Log("文件已存在,删除数据");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
File.WriteAllBytes(filepath, bytes);
}
else
{
Debug.Log("文件不存在,写入数据");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
File.WriteAllBytes(filepath, bytes);
}
*/
#endregion
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
//创建复合数组型Json附带标题
void CreatJsonArrayDemo4()
{
//用户数据1
JsonData j1 = new JsonData();
j1["id"] = 0;
j1["name"] = "Huawei";
j1["industry"] = "electronic";
j1["product"] = "mobile";
//用户数据2
JsonData j2 = new JsonData();
j2["id"] = 1;
j2["name"] = "Apple";
j2["industry"] = "electronic";
j2["product"] = "Iphone";
//用户数据3
JsonData j3 = new JsonData();
j3["id"] = 2;
j3["name"] = "小米";
j3["industry"] = "electronic";
j3["product"] = "Xiaomi";
//添加到数组中
#region 写法1
JsonData Arr = new JsonData()
{
j1,
j2,
j3
};
JsonData jd = new JsonData();
#endregion
#region 写法2
/*
JsonData Arr = new JsonData();
JsonData jd = new JsonData()
Arr.Add(j1);
Arr.Add(j2);
Arr.Add(j3);
*/
#endregion
//添加标题=tag
jd["华为"] = Arr[0];
jd["苹果"] = Arr[1];
jd["小米"] = Arr[2];
string json = jd.ToJson();
//转译Json中文
string s = ParseJsonData(json);
//创建
CreatJsonFile(s);
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
//传入待转换的Json字符串,取得转换后的Json数据写入文件中
string ParseJsonData(string json)
{
Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
string targetJson = reg.Replace(json, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
return targetJson;
}
void ModifyJson(string json)
{
if (File.Exists(filepath))
{
File.Delete(filepath);
Debug.Log("文件已存在,删除数据");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
File.WriteAllBytes(filepath, bytes);
}
else
{
Debug.Log("文件不存在,写入数据");
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json);
File.WriteAllBytes(filepath, bytes);
}
#if UNITY_EDITOR
AssetDatabase.Refresh();
#endif
}
//修改Json数据--(复杂删)
void DeletJsonData(string arrName,int index,string key="")
{
JsonData jd = ReadJsonData();//原文件数据
if (string.IsNullOrEmpty(key))
{
#region 删除数组某个索引的整体数据,如arr[1]
JObject jot1 = new JObject();
JArray arrJA = JArray.Parse(jd[arrName].ToJson());
arrJA.RemoveAt(index);//测试Remove Token不行
//新数据
jot1[arrName] = arrJA;
string jot1Str = jot1.ToString();
string jdt = ParseJsonData(jot1Str);
CreatJsonFile(jdt);//写入
#endregion
}
else
{
#region 删除数组某个索引里的单个key数据,如arr[1]["name"]
JsonData j1 = jd[arrName][index];
//去除数组里索引为index的单个数据key,如去除name
JObject jo = JObject.Parse(j1.ToJson());
jo.Remove(key);
//缓存删除key后的数据
JArray array = new JArray();
for (int i = 0; i < jd[arrName].Count; i++)
{
array.Add(null);
}
array[index] = jo;//缓存去除key后数组里索引为index的数据
JObject jobt = new JObject();
//原Json表中数组信息写入(不包含去除key的数据)
for (int i = 0; i < jd[arrName].Count; i++)
{
if (i == index) continue;
array[i] = JObject.Parse(jd[arrName][i].ToJson());
}
//新数组数据
jobt[arrName] = array;
string jobtStr = jobt.ToString();
string jsonDt = ParseJsonData(jobtStr);
CreatJsonFile(jsonDt);//写入
#endregion
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
//创建简单Json数据
JsonSimpleDemo1();
}
if (Input.GetKeyDown(KeyCode.W))
{
//创建简单数组型Json数据
JsonSimpleArrayDemo1();
}
if (Input.GetKeyDown(KeyCode.E))
{
//使用JsonWriter写入数据
JsonWriterDemo();
}
if (Input.GetKeyDown(KeyCode.R))
{
//string s = ReadJsonData().ToString();
// AddNewData(s);
}
if (Input.GetKeyDown(KeyCode.T))
{
CreatJsonArrayDemo4();//创建数组型附带Tag标题
//测试读取文件
JsonData jd = ReadJsonData();
Debug.Log(jd["苹果"]["name"]);//Apple
}
//创建数组型以及新增用户数据--(增)
if (Input.GetKeyDown(KeyCode.Y))
{
CreatJsonArrayDemo3();
//读取原数据
JsonData jd = ReadJsonData();
//新增用户数据j4
JsonData j4 = new JsonData();
j4["id"] = 3;
j4["name"] = "OPPO";
j4["industry"] = "electronic";
j4["product"] = "oppo";
//原数组add
jd["info"].Add(j4);
string s = jd.ToJson();
string t = ParseJsonData(s);//转译中文显示
CreatJsonFile(t);
}
//修改Json数据--(改)
if (Input.GetKeyDown(KeyCode.U))
{
JsonSimpleDemo1();
JsonData jd = ReadJsonData();
if (jd["sex"].IsInt)
{
jd["sex"] = 0;
}
ModifyJson(jd.ToJson());
}
//修改Json数据--(简易删)
if (Input.GetKeyDown(KeyCode.I))
{
// Q键按下创建Json文件,I键测试删除key
JsonData jd = ReadJsonData();
//要删除的数据
if (jd["sex"].IsInt)
{
JObject jo = JObject.Parse(jd.ToJson());
jo.Remove("sex");
Debug.Log(jo.ToString());
CreatJsonFile(jo.ToString());//写入新数据
}
}
//修改Json数据--(复杂删)
if (Input.GetKeyDown(KeyCode.P))
{
//先创建文件
// CreatJsonArrayDemo3();
string key = "product";
string arrName = "info";
DeletJsonData(arrName,1);//删除这个数组里索引为1的整组数据
// DeletJsonData(arrName, 1,key);//删除这个数组里索引为1的单个key数据
}
//查找Json数据--(查)
if (Input.GetKeyDown(KeyCode.F))
{
//要求:先创建
CreatJsonArrayDemo3();
//取得该标签2/3的Json数据
List<JContainer> list = FindJsonData(2, 3);
JsonData jd = ReadJsonData();//原文件数据
var o = JObject.Parse(jd.ToJson());
for (int i = 0; i < list.Count; i++)
{
string path = (list[i].Path);
string name= o.SelectToken(path + ".name").ToString();
print(name);
}
}
}
}
关于在Json文件中增加新的数据(LitJson.dll)
关于在Json文件中修改已有的数据(LitJson.dll)
删除已有的简单Json数据(使用JObject需要Newtonsoft.Json.dll)
删除复杂数据(数组以及数组里的单个数据)参考代码中的Jarray部分
关于在Json文件中查找Json数据(使用JObject需要Newtonsoft.Json.dll)
例如:删选Json数据中带同种tag类型的数据
参考脚本F键的测试
相应文件提供:
1:旧脚本以及LitJson.dll文件 Json.20180510_免费高速下载|百度网盘-分享无限制 (旧脚本自己备份用,dll文件可下载)
本文参考链接:
1:【代码日志】Unity动态读取json文件数据并存储到类对象中进行调用(双层嵌套数据结构) - 知乎 知乎
2:Unity中Json创建,解析_heyuchang666的专栏-CSDN博客 Json的创建以及解析
3:Json写入和读取_XIAO_11_DONG的博客-CSDN博客_json数组写入和读取顺序
4:LitJson删除单条数据_code changes world!-CSDN博客_litjson 删除某个节点 删除单条数据参考
5:https://github.com/SaladLab/Json.Net.Unity3D/releases 下载Json.Net 9.0.1
PS:欢迎大家交流学习!