返回「计算机、信息技术与工程」

序列化与反序列化

更多
Markdown 结构化数据
本文目录 16 个章节

序列化与反序列化

创建时间:2020/6/9 14:33

Ref: https://zhuanlan.zhihu.com/p/27990334

概念

序列化 又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形式使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。

序列化

序列化是指把 对象 转换为 字节序列 的过程

对象序列化的最主要的用处就是在 传递和保存对象 的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了 对象的状态以及相关的描述信息 。序列化机制的核心作用就是对象状态的保存与重建。

反序列化

反序列化是指把 字节序列 (有序字节流)恢复为 对象 的过程

客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化 重建对象,恢复对象状态

作用

  1. 永久性保存对象,保存对象的字节序列到本地文件或者数据库中;

  2. 通过序列化以字节流的形式使对象在网络中进行传递和接收;

  3. 通过序列化在进程间传递对象;

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(自动序列化)

使用方法

需要指定创建的目录和资源名称,如果资源已经存在,则不会创建新资源;

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

  1. SetXXX : 是你要储存的数据类型,这里必须是一组键值对,第一个参数是Key,第二个参数是对应的Value。

  2. GetXXX:这里是获取数据的函数,只有一个参数Key,用来获取对应Key的Value. 3.HasKey: 这个可以用来做判断。比如有两组数据一组有XX这个Key,另一组没有XX这个Key,这个时候我们就可以对这两组数据进行差异化操作。

  3. DeleteXX:用于删除数据。

  4. Save:用于在突发退出程序时,保存数据以备恢复时使用,但是会导致程序间断所以不建议调用。