Unity序列化和反序列化——二进制、JSON、XML

序列化可以将对象转换为字节序列后存储在数据库、内存或者文件中;

File类

静态类,对文件进行操作,静态方法提供文件的创建、复制、剪切、打开,可以直接赋值到FileStream类。命名空间为System.IO

FileStream类

用来读取和写入操作系统文件,将文件的内容以字节流的形式呈现出来进行操作,可以读取(Load)、写入(Save)、关闭(Close)文件流,用完记得关闭文件流;

BinaryFormattter类

以二进制格式序列化和反序列化对象。通常数据会保存到硬盘中,所以即使之后推出运行模式,加载数据文件同样可以读取数据。
BinaryFormattter.Serialize(Stream,Object):将对象序列化到给定的流;
BinaryFormattter.DeSerialize(Stream):将指定的流反序列化成对象,即读取的过程;

二进制方法

二进制方法阅读性差,兼容性不高;
不用挂到物体,不继承monobehaviour;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


//所有需要保存的数据声明在这个类,其他脚本调用时声明实例即可;
[System.Serializable]
public class Save
{
    
    
    public float posX;
    public float posY;
}

脚本挂到物体上,添加两个按钮试一下效果

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using UnityEngine.UI;

public class GameControl : MonoBehaviour
{
    
    

    public GameObject save;
    public GameObject load;

    private void Awake()
    {
    
    
        save = GameObject.Find("ButtonManager/Canvas/Save");
        load = GameObject.Find("ButtonManager/Canvas/Load");
        save.GetComponent<Button>().onClick.AddListener(SaveBySerialization);
        load.GetComponent<Button>().onClick.AddListener(LoadByDeserialization);
    }

    private Save CreateSaveGameObject() {
    
    
        Save save = new Save();
        save.posX = gameObject.transform.position.x;
        save.posY= gameObject.transform.position.y;
        return save;
    
    }

    private void SaveBySerialization() {
    
    
        Save save = CreateSaveGameObject();
        BinaryFormatter bf = new BinaryFormatter();
        //步骤:创建文件流——序列化Save对象并写入硬盘——关闭文件流
        //文件在assets目录下
        FileStream fileStream = File.Create(Application.dataPath + "/Data.text");

        bf.Serialize(fileStream, save);
        fileStream.Close();
        Debug.Log("save:   "+gameObject.transform.position);
    }

    private void LoadByDeserialization() {
    
    
        //首先检查安全性
        if (File.Exists(Application.dataPath + "/Data.text"))
        {
    
    
            BinaryFormatter bf = new BinaryFormatter();
            FileStream fileStream = File.Open(Application.dataPath + "/Data.text",FileMode.Open);
            Save save = bf.Deserialize(fileStream) as Save ;
            fileStream.Close();
            gameObject.transform.position = new Vector2(save.posX,save.posY);
            Debug.Log("load:   " + gameObject.transform.position);
        }
        else {
    
    
            Debug.Log("NOT FOUND THIS FILE!");
        }
    
    }
}

JSON方法

JSON是一种轻量级的数据交换格式——数据格式比较简单,格式可压缩,占用带宽小,解析速度快;JSON格式是以键值对的形式展示;
这里使用unity自带的JsonUtility类解析Json数据——解析快并且GC少;
JsonUtility.ToJson(Object obj): 对象转换成Json类;
JsonUtility.FromJson(String _string): Json转换成对象;
缺点:虽然人可读性好,但机器可读性差;

 #region Json方法 
    //Json是String类型
    private void SaveByJson()
    {
    
    
        Save save = CreateSaveGameObject();
        string jsonString = JsonUtility.ToJson(save);
        //不同文本有不同的编码格式,StreamWriter会自动处理,不需要关心文本文件的编码是什么
        //FileStream读取的是字节数组,使用非文本文件,所以它适合读取二进制文件
        StreamWriter sw = new StreamWriter(Application.dataPath + "/JsonData.text");
        sw.Write(jsonString);
        sw.Close();
        Debug.Log("-------Save------");


    }

    private void LoadByJson()
    {
    
    
        if (File.Exists(Application.dataPath + "/JsonData.text"))
        {
    
    
            StreamReader sr = new StreamReader(Application.dataPath + "/JsonData.text");
            //从当前位置读到结束,Read方法只会读一个字符
            string jsonString = sr.ReadToEnd();
            sr.Close();
            Save save = JsonUtility.FromJson<Save>(jsonString);
            gameObject.transform.position = new Vector2(save.posX, save.posY);
            Debug.Log("-------Load------");

        }
        else
        {
    
    
            Debug.Log("NOT FOUND THIS FILE!");
        }
    }


    #endregion

xml方法

可扩展标记语言,xml被设计用来结构化的存储和传输数据,xml以纯文本格式进行存储,可以在不兼容的系统之间轻松交换数据,xml简化数据共享,本质是字符串;
xml和HTML的区别:HTML主要关注网页的内容显示,xml更关注数据信息存储了什么;
xml使用XmlDocument类来保存和加载xml文档,静态方法提供创建、保存、读取、添加、删除xml文件,命名空间为System.Xml;

 #region xml
    private void SaveByXML() {
    
    
        Save save = CreateSaveGameObject();
        XmlDocument xmlDocument = new XmlDocument();
        #region CreateXML elements
        //创建根节点
        XmlElement root = xmlDocument.CreateElement("Save"); // <Save>....elements....</Save>
        root.SetAttribute("FileName", "File_01");//可选

        XmlElement posXElement = xmlDocument.CreateElement("posX");
        posXElement.InnerText = save.posX.ToString();
        root.AppendChild(posXElement);

        XmlElement posYElement = xmlDocument.CreateElement("posY");
        posYElement.InnerText = save.posY.ToString();
        root.AppendChild(posYElement);

        #endregion
        xmlDocument.AppendChild(root);
        xmlDocument.Save(Application.dataPath + "/DataXML.text");
        Debug.Log("------Save--------");

    
    }
    private void LoadByXML() {
    
    
        if (File.Exists(Application.dataPath + "/DataXML.text"))
        {
    
    
            Save save = new Save();
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(Application.dataPath + "/DataXML.text");
            //通过Tag标签访问元素中具体的数值,返回的是List列表,第一个是posX[0],第二个是posX[1];
            XmlNodeList posX = xmlDocument.GetElementsByTagName("posX");
            float pos_X = float.Parse(posX[0].InnerText);
            save.posX = pos_X;

            XmlNodeList posY = xmlDocument.GetElementsByTagName("posY");
            float pos_Y = float.Parse(posY[0].InnerText);
            save.posY = pos_Y;
            gameObject.transform.position = new Vector2(save.posX, save.posY);
            Debug.Log("------Load-------");
        } 
        else 
        {
    
    
            Debug.Log("NOT FOUND THIS FILE!");
        }

    }


    #endregion

三者的优劣

二进制:无法阅读,但能防止别人篡改;
JSON:体积小,传输快,可读性不如XML,但编码更简单,在网页的javascript中有更好的交互;
XML:需要考虑根元素和子元素,加载过程中还要通过标签名找到xml元素的集合,存在大量冗余、重复的标签,占用空间最大,文件格式复杂,解析需要较多的资源和时间。但是如果需要保存大量数据,xml文件的格式符合标准,与其他系统远程交互方便,数据共享的难度较低。
Json和XML是不可以互相替代的。

猜你喜欢

转载自blog.csdn.net/memory_MM_forever/article/details/118407469