序列化

it2025-10-04  13

简介

序列化:将对象保存到文件或数据库(虚的->实质)

反序列化:从文件数据中转化为原来对象(实质->虚的)

C#常见的序列化有三种:BinaryFormatter、SoapFormatter、XML

作用

进程下次启动读取上次保存的对象信息不同进程间传递数据

要求

public类型或者有[SerializeField]属性不是static、const、readonly类型必须是Unity可以序列化的类型

实例

BinaryFormatter

using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System; public class Test : MonoBehaviour { void Start() { SerializeToFile(); } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { SerializeFromFile(); } } void SerializeToFile() { MyObj obj = new MyObj(); obj.Id = 1; obj.Count = 1; obj.Name = "obj"; BinaryFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("Myfile.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(stream, obj); stream.Close(); } void SerializeFromFile() { BinaryFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("Myfile.bin", FileMode.Open, FileAccess.Read, FileShare.Read); MyObj obj = (MyObj)formatter.Deserialize(stream); stream.Close(); Debug.LogError( "id:" + obj.Id+"\n"+ "count:"+obj.Count+"\n"+ "name:"+obj.Name ); } } [Serializable] public class MyObj { public int Id; public int Count; public string Name; } 添加Serializable属性使类可序列化效率很高,能生成非常紧凑的字节流反序列化时不调用构造函数子类无法继承Serializable属性

SoapFormatter

代码类似 将BinaryFormatter改为SoapFormatter 将Myfile.bin改为Myfile.soap

Soap文件(简单对象访问协议)是一种轻量的、简单的、基于XML的协议,主要用于WEB交互

XML

代码类似 将BinaryFormatter改为XmlSerializer 将Myfile.bin改为Myfile.xml

选择性序列化

NonSerialized:类可能包含不应被序列化的字段。如,某个类的一个成员变量存储着线程ID,当被反序列化时,可能线程不运行,那么这个值反序列化就没有意义

[Serializable] public class MyObj { public int Id; [NonSerialized] public int Count; public string Name; }

输出Count=0

自定义序列化

有一种情况是这样:序列化好了一个文件,可是没注意文件损坏,反序列化时就会出错

ISerializable :实现此接口的对象可以自定义序列化过程,在反序列化失效时尤其有用,需要先为变量提供值以保证可以重建对象的完整状态

序列化时需要实现GetObjectData 方法,反序列化时需要用到一个特殊的构造函数

[Serializable] public class MyObj : ISerializable { public int Id; public int Count; public string Name; public MyObj() { } //实现接口方法 public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("a1", Id); info.AddValue("a2", Count); info.AddValue("a3", Name); } //构造函数 private MyObj(SerializationInfo info, StreamingContext context) { Id = info.GetInt32("a1"); Count = info.GetInt32("a2"); Name = info.GetString("a3"); } }

其中,value键值对名称只要对应就可以

总结

三种方式 BinaryFormatter、SoapFormatter、XML三个属性 Serializable、NonSerialized、SerializeField一个接口 ISerializable要小心使用序列化,因为序列化并不是运行在主线程!

参考

https://www.cnblogs.com/devhyj/p/4342592.html

最新回复(0)