Unity中JSON序列化与反序列化

来源:互联网 发布:威海市南海新区知乎 编辑:程序博客网 时间:2024/06/06 12:27

.JSON介绍

        JSON是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

二.JSON语法规则

对象表示为键值对

数据由逗号分隔

花括号保存对象

方括号保存数组

三.JSON序列化

第一种序列化

1.字符串转比特数组

 

(1)byte[] bt=System.Text.Encoding.Default.GetBytes("字符串");

 

(2)byte[] bt=Convert.FromBase64String("字符串");

 

2.字符串转流

 

(1)MemoryStream ms=new MemoryStream(System.Text.Encoding.Default.GetBytes("字符串"));

 

(2)MemoryStream ms=new MemoryStream(Convert.FromBase64String("字符串"));

 

3.流转比特数组

 

(1)byte[] bt=ms.ToArray();

 

(2)MemoryStream ms=new MemoryStream();ms.Write(bt,0,ms.Length);

 

4.流转字符串

 

(1)string str=Convert.ToBase64String(ms.ToArray());

 

(2)string str=System.Text.Encoding.Default.GetString(ms.ToArray());

 

5.比特数组转字符串

 

(1)string str=System.Text.Encoding.Default.GetString(bt);

 

(2)string str=Convert.ToBase64String(bt);

 

6.比特数组转流

 

(1)MemoryStream ms=new MemoryStream(bt);

 

(2)MemoryStream ms=new MemoryStream();ms.Read(bt,0,bt.Lenght);


1. 添加引用System.ServiceModel.Web

2. 创建类

[csharp] view plain copy
public class JsonHelper  
 {  
     // 序列化  
     public static  string JsonSerializer<T>(T t)  
     {  
         // 使用 DataContractJsonSerializer 将 T 对象序列化为内存流。   
         DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof (T));  
         MemoryStream ms = new MemoryStream();  
         // 使用 WriteObject 方法将 JSON 数据写入到流中。   
         jsonSerializer.WriteObject(ms, t);  
         // 流转字符串  
         string jsonString = Encoding.UTF8.GetString(ms.ToArray());  
         ms.Close();  
         //替换Json的Date字符串    
         string p = @"\\/Date(\d+)\+\d+\\/";     
         MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);    
         Regex reg = new Regex(p);     
         jsonString = reg.Replace(jsonString, matchEvaluator);  
         return jsonString;  
     }  
     public static T JsonDeserialize<T>(string  jsonString)  
     {  
         //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式    
         string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";     
         MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);     
         Regex reg = new Regex(p);    
         jsonString = reg.Replace(jsonString, matchEvaluator);  
         DataContractJsonSerializer jsonSerializer=new DataContractJsonSerializer(typeof(T));  
         // 字符串转流  
         MemoryStream ms=new MemoryStream(Encoding.UTF8.GetBytes(jsonString));  
         // 通过使用 DataContractJsonSerializer 的 ReadObject 方法,将 JSON 编码数据反序列化为T   
         T obj = (T) jsonSerializer.ReadObject(ms);  
         return obj;  
     }  
     public static string ConvertJsonDateToDateString(Match match)  
     {  
         string result = string.Empty;  
         DateTime dateTime=new DateTime(1970,1,1);  
         dateTime = dateTime.AddMilliseconds(long.Parse(match.Groups[1].Value));  
         dateTime = dateTime.ToLocalTime();  
         result = dateTime.ToString("yyyy-MM-dd HH:mm:ss");  
         return result;  
     }  
     private static string ConvertDateStringToJsonDate(Match m)  
     {  
         string result = string.Empty;     
         DateTime dt = DateTime.Parse(m.Groups[0].Value);   
         dt = dt.ToUniversalTime();     
         TimeSpan ts = dt - DateTime.Parse("1970-01-01");    
         result = string.Format("\\/Date({0}+0800)\\/",ts.TotalMilliseconds);     
         return result;     
     }  
 }  
 public class Person  
 {  
     public string Name { get; set; }  
     public int Age { get; set; }  
     public DateTime dateTime { get; set; }  
 }  

3. 后台代码实现
[csharp] view plain copy
protected void Page_Load(object sender, EventArgs e)  
       {  
           // 序列化  
           Person p = new Person();  
           p.Name = "Bradley";  
           p.Age = 24;  
           p.dateTime = DateTime.Now;  
           string jsonString = JsonHelper.JsonSerializer<Person>(p);  
           Response.Write(jsonString);  
           Response.Write("</br>");  
           // 反序列化  
           string jsonString1 = "{\"Age\":28,\"Name\":\"张三\"}";      
           Person p1 = JsonHelper.JsonDeserialize<Person>(jsonString);  
           Response.Write(p1.Name+":"+p1.Age.ToString()+"Time:"+p.dateTime.ToString());  
  
           // 序列化字典  
           Dictionary<string,string> dictionary=new Dictionary<string, string>();  
           dictionary.Add("Name:","Bradley");  
           dictionary.Add("Age:","24");  
           string jsonString2 = JsonHelper.JsonSerializer<Dictionary<string, string>>(dictionary);  
           Response.Write("</br>");  
           Response.Write(jsonString2);  
       }  


     第二种--Unity 使用JsonFx进行JSON (反)序列

      背景

Unity作为客户端要与服务端通信,最为简单通信协议就是使用Json格式。本文简单讲述Unity使用JsonFx进行Json(反)序列。
序列和反序列是一个互为逆反的过程。反序列化可以帮助我们将已从文本中读取的一个字符串(确切是符合Json的字符串)解析成一种类型的数据实例,并且加载到内存中,直到我们摧毁它或停止应用程序。一旦我们在 unity 编辑器 (或关闭我们build生成中的窗口)关闭播放play模式,该数据就丢失了。而序列化是为了将其存储到文件系统中,不仅我们可以脱机编辑,而且当我们再次加载它,可以查看更改反映在我们的应用程序。
1. JsonFx
JsonFx是一个JSON (反)序列的插件
2. 创建容器
容器其实是你想通过json字符串解析出来的类,它包含了若干个字段数据,例如Sandwich类
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class Sandwich{
    public string name;
    public string bread;
    public float price;
    public List<string> ingredients = new List<string>();
}
在Sanwich.cs中,共有name, bread, price, ingredients等字段,只是注意字段都是public的,这一点很重要! 此外,[System.Serializable] 能为我们做两件事: 它允许 JsonFx 要序列化的字段,显示到inspector面板上,将这些字段。
那应该怎么样的json字符串才能解析出来呢?
3. 反序列数据
反序列json字符串其实也非常简单,只需要遵循以下规则:
json字符串的key要与类的字段名(key)要一致;
json字符串的value要与类的字段名申明的类型一致;
例如,上述的Sanwich类的一个可行的反序列json字符串为:
string sandwich_json = "{\"name\":\"haqi\", \"bread\":\"tudo
usi\",  \"price\":1.45, \"ingredients\":[\"sala\",\"beef
\",\"cheese\",\"whatever\"]}";
举个例子
例子是上述Sandwich由反序列,然后序列化,最后保存的完整代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using JsonFx.Json;
using System.IO;
// Sanwich类
[System.Serializable]
public class Sandwich{
    public string name;
    public string bread;
    public float price;
    public List<string> ingredients = new List<string>();
}
public class Test : MonoBehaviour {
    void Start(){
        //准备反序列化json字符串
        string sandwich_json = "{\"name\":\"haqi\", \"bread\":\"tudousi\",  \"price\":1.45, \"ingredients\":[\"sala\",\"beef\",\"cheese\",\"whatever\"]}";
        // 反序列化,下个函数
        Sandwich sw = Deserialize (sandwich_json);
        // 修改属性
        sw.bread = "this_bread_is_changed";
        // 序列化并且保存,下下个函数
        SerializeAndSave (sw);
    }
    // 反序列化
    Sandwich Deserialize(string sw_json){
        // 使用JsonFx反序列功能
        Sandwich sw = JsonReader.Deserialize<Sandwich> (sw_json);
        Debug.Log ("name:" + sw.name);
        Debug.Log ("bread:" + sw.bread);
        Debug.Log ("price:" + sw.price.ToString());
        Debug.Log ("first ingredients:" + sw.ingredients[0]);
        return sw;
    }
    void SerializeAndSave(Sandwich sw) {
        // 使用JsonFx序列化功能
        string data = JsonWriter.Serialize(sw);
        //持久化
        var streamWriter = new StreamWriter(Path.Combine(Application.persistentDataPath, "serialize_sandwich.json"));
        streamWriter.Write(data);
        streamWriter.Close();
    }
}
最后修改了Sandwich实例,并且持久化到“serialize_sandwich.json”内容为:
{"name":"haqi","bread":"this_bread_is_changed","price":1.45,"ingredients":["sala","beef","cheese","whatever"]}

四.和XML的比较

可读性
JSON和XML的可读性可谓不相上下,一边是简易的语法,一边是规范的标签形式,很难分出胜负。
可扩展性
XML天生有很好的扩展性,JSON当然也有,没有什么是XML可以扩展而JSON却不能扩展的。不过JSON在Javascript主场作战,可以存储Javascript复合对象,有着xml不可比拟的优势。
编码难度
XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有提供的工具。无工具的情况下,相信熟练的开发人员一样能很快的写出想要的xml文档和JSON字符串,不过,xml文档要多很多结构上的字符。
解码难度
XML的解析方式有两种:
一是通过文档模型解析,也就是通过父标签索引出一组标记。例如:xmlData.getElementsByTagName("tagName"),但是这样是要在预先知道文档结构的情况下使用,无法进行通用的封装。
另外一种方法是遍历节点(document 以及 childNodes)。这个可以通过递归来实现,不过解析出来的数据仍旧是形式各异,往往也不能满足预先的要求。
凡是这样可扩展的结构数据解析起来一定都很困难。
JSON也同样如此。如果预先知道JSON结构的情况下,使用JSON进行数据传递简直是太美妙了,可以写出很实用美观可读性强的代码。如果你是纯粹的前台开发人员,一定会非常喜欢JSON。但是如果你是一个应用开发人员,就不是那么喜欢了,毕竟xml才是真正的结构化标记语言,用于进行数据传递。
而如果不知道JSON的结构而去解析JSON的话,那简直是噩梦。费时费力不说,代码也会变得冗余拖沓,得到的结果也不尽人意。但是这样也不影响众多前台开发人员选择JSON。因为json.js中的toJSONString()就可以看到JSON的字符串结构。当然不是使用这个字符串,这样仍旧是噩梦。常用JSON的人看到这个字符串之后,就对JSON的结构很明了了,就更容易的操作JSON。
以上是在Javascript中仅对于数据传递的xml与JSON的解析。在Javascript地盘内,JSON毕竟是主场作战,其优势当然要远远优越于xml。如果JSON中存储Javascript复合对象,而且不知道其结构的话,我相信很多程序员也一样是哭着解析JSON的。
除了上述之外,JSON和XML还有另外一个很大的区别在于有效数据率。JSON作为数据包格式传输的时候具有更高的效率,这是因为JSON不像XML那样需要有严格的闭合标签,这就让有效数据量与总数据包比大大提升,从而减少同等数据流量的情况下,网络的传输压力

实例比较

XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。
用XML表示中国部分省市数据如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<country>
    <name>中国</name>
    <province>
        <name>黑龙江</name>
        <cities>
            <city>哈尔滨</city>
            <city>大庆</city>
        </cities>
    </province>
    <province>
        <name>广东</name>
        <cities>
            <city>广州</city>
            <city>深圳</city>
            <city>珠海</city>
        </cities>
    </province>
    <province>
        <name>台湾</name>
        <cities>
            <city>台北</city>
            <city>高雄</city>
        </cities>
    </province>
    <province>
        <name>新疆</name>
        <cities>
            <city>乌鲁木齐</city>
        </cities>
    </province>
</country>
用JSON表示如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
    "name": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "台湾",
        "cities": {
            "city": ["台北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}
可以看到,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得带宽。




原创粉丝点击