序列化可以将对象转换为字节序列后存储在数据库、内存或者文件中;
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是不可以互相替代的。