Unity(九) 使用json保存角色信息并增、改数据以及修改json转译下的中文显示

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格式如下

  1.   依次为简单Json         -> JsonSimpleDemo1()
  2. JsonWriter创建数组Json     -> JsonWriterDemo()
  3. 数组型Json      -> CreatJsonArrayDemo4()
  4.  数组型Json(增加数据)   -> CreatJsonArrayDemo3()新脚本增加了tag数据图5
  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:欢迎大家交流学习!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值