序列化与反序列化
本文目录 16 个章节
序列化与反序列化
创建时间:2020/6/9 14:33
Ref: https://zhuanlan.zhihu.com/p/27990334
概念
序列化 又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形式使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。
序列化
序列化是指把 对象 转换为 字节序列 的过程
对象序列化的最主要的用处就是在 传递和保存对象 的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了 对象的状态以及相关的描述信息 。序列化机制的核心作用就是对象状态的保存与重建。
反序列化
反序列化是指把 字节序列 (有序字节流)恢复为 对象 的过程
客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化 重建对象,恢复对象状态
作用
永久性保存对象,保存对象的字节序列到本地文件或者数据库中;
通过序列化以字节流的形式使对象在网络中进行传递和接收;
通过序列化在进程间传递对象;
Unity序列化
Unity的场景文件和预制体默认就是以二进制的文件保存在工程目录下。 在 检视面板 中可以看到的,就是被 成功序列化了的参数 。与序列化相关的常用的关键字如下,可以组合使用。
SerializeField : 表示变量可被序列化。众所周知,公有变量可以在检视面板中看到并编辑,而私有和保护变量不行。SerializeField与private,protected结合使用可以达到让脚本的变量在检视面板里可视化编辑,同时保持它的私有性的目的。
HideInInspector : 将原本显示在检视面板上的序列化值隐藏起来。
NonSerialized :通过此方法可以将一个公有变量不序列化并且不显示在检视面板中。
Serializable:用在类的前面,表示该类可被序列化。
相关API SerializedObject: https://docs.unity3d.com/ScriptReference/SerializedObject.html SerializedProperty: https://docs.unity3d.com/ScriptReference/SerializedProperty.html
注意:并非所有的公有变量都是可以被序列化的。其中const,static是静态的,属于类而非对象,无法序列化。链表和字典在内存中的存储是不连续的,也无法序列化。其中const,static,readonly的区别可参考文章:https://www.cnblogs.com/suizhikuo/p/4739388.html
Demo
二进制方法(Binary Formatter)
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
注意:二进制方法可以序列化私有变量,不能序列化被[NonSerialized ]修饰的变量且类需要被[Serializable ]标识。
Xml序列化
XML(Extensible Markup Language, 可扩展标记语言), 标准通用标记语言(Standard Generalized Markup language, SGML)的子集。是一种用于标记电子文件使其具有结构性的标记语言。 提供统一的方法来描述和交换独立于应用程序或供应商的 结构化数据 。
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
其他Unity数据存储方法
ScriptableObject(自动序列化)
使用方法
MenuItem
需要指定创建的目录和资源名称,如果资源已经存在,则不会创建新资源;
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
CreateAssetMenu
可以在Assets下任意目录创建资源,而且可以创建多个资源;
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
在Assets下创建一个可编程对象资源,设置好所需数据;如果需要在其它脚本中获取该数据,是需要声明一个该类型变量,然后为其赋值或加载该数据资源;然后,就像使用用一个类中的公有变量一样使用即可;
class Program
{
static void Main(string[] args)
{
dynamic dyn = 1;
object obj = 1;
dyn = dyn + 3;
//obj = obj + 3; 报错
// Rest the mouse pointer over dyn and obj to see their
// types at compile time.
System.Console.WriteLine(dyn.GetType());
System.Console.WriteLine(obj.GetType());
}
}
PlayerPrefs
Ref: https://www.jianshu.com/p/579be3b8e1e3 PlayerPrefs是Unity内置的一个静态类,可以用于存储一些简单的数据类型:int ,string ,float。可以用它来做成计分板这类需要可持续化存储的小地方。
PlayerPrefs数据存储在哪里?
1.在Mac OS X上存储在~/Library/PlayerPrefs文件夹,名为unity.[company name].[product name].plist,这里company和product名是在project Setting中设置的 2.在windows下,playerPrefs被存储在注册的HKCU\Software[company name][product name]键下,这里company和product名是在project setting中设置的。 3.在Android上,数据存储(持久化)在设备上。数据保存在SharedPreferences中。
PlayerPrefs有哪些方法?
分为五类:SetXXX , GetXXX , DeleteXXX, HasKey , Save. 传送门:https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
SetXXX : 是你要储存的数据类型,这里必须是一组键值对,第一个参数是Key,第二个参数是对应的Value。
GetXXX:这里是获取数据的函数,只有一个参数Key,用来获取对应Key的Value. 3.HasKey: 这个可以用来做判断。比如有两组数据一组有XX这个Key,另一组没有XX这个Key,这个时候我们就可以对这两组数据进行差异化操作。
DeleteXX:用于删除数据。
Save:用于在突发退出程序时,保存数据以备恢复时使用,但是会导致程序间断所以不建议调用。