对象序列化和反序列化是什么?

24

什么是对象序列化反序列化

与普通技术(如读取对象的属性,然后将DataRow的列填充到它们中,最后将DataRow保存在DB中)相比,序列化有何不同之处?


1
可能是什么是对象序列化?的重复问题。 - nbro
这是一个短视频解释,请点击链接观看:https://youtu.be/BQFYQPfERIE - VedantK
5个回答

38

序列化通常是指创建数据的版本(而不是对象),该版本可以用于存储(例如在文件中),在网络上传输,或者仅在单台计算机上在进程 / AppDomain /等之间传输。

序列化通常意味着将数据编写为字符串(比如:xml / json)或原始二进制格式(例如:byte[]等)。反序列化是相反的过程;它会获取原始数据(来自文件,来自传入的网络套接字等),并重新构建对象模型。

与使用数据库的区别在于,它没有固有的表格布局,也没有真正的绑定到数据库;数据可以是任何形状,并且倾向于更接近面向对象的布局,而不是表格的行/列性质。

大多数平台都有一系列序列化工具。例如,听起来您正在谈论.NET-因此BinaryFormatter(.NET特定),XmlSerializerDataContractSerializer,Json.NET和protobuf-net / dotnet-protobufs都符合要求。


你好,我有以下问题:1.为什么我们需要对对象进行序列化?2.当序列化一个对象时会发生什么?3.当序列化一个对象时我们得到了什么?4.为什么不将对象存储在内存中而是使用序列化数据?究竟是什么以及为什么我们需要这个被称为序列化的概念?如果序列化将成为可流式传输的,那么在计算机科学中“可流式传输”究竟意味着什么?即使您提供链接或其他参考资料,对我来说也没问题。 - Vikash
4
@Vikash,你曾经需要“存储”数据吗?在文件系统中或作为数据库中原始的clob/blob字段?或在同一台机器上的进程之间交换数据?甚至可能将数据发送到另一台机器上的进程上(本地或互联网)?所有这些都需要序列化。本地进程空间中的对象仅可由该进程在该机器上访问,在该进程的有限生命周期内可用。 - Marc Gravell

7
序列化 = 将对象的相关状态放入可流式表示中。这可能意味着将其转换为字节流。这不一定包括将每个成员变量复制到流中。在Effective Java中由Joshua Bloch使用的经典示例是HashSet。您只需序列化Hashset中的元素而不是键。
反序列化 = 从序列化表示中恢复对象并确保对象的不变性。反序列化可以被视为对象的单独构造函数。对于上述提到的HashSet,您将创建一个新的HashSet,然后将流中的值插入到这个新数据结构中。

1
赞了一下源词的提示。序列化将一个对象树(层次结构)转换为串行(平面)表示,而不会丢失语义。 - Daren Thomas
1
这与将其从“树”转换为“平面”表示形式无关。您可以将其序列化到仍处于树格式的数据库中,并从其中反序列化。这并不相关。 - Noon Silk
1
我认为通常情况下,数据库版本不是对象的串行版本。对象中包含的数据可以分成多个表。序列化的想法是创建一个可以逐位传输(即串行传输)的表示。 - jens

5
序列化意味着将对象持久化为一种表示形式,以便您可以在某处存储它。一种方法是仅采用指向对象在内存中存储位置的指针,并将每个字节按原样写入文件。由于该表示形式非常特定于您的编程语言(以及它如何表示内存中的对象),因此改进方法是将对象转换为字符串表示形式,该字符串具有特定的已知结构(例如XML或JSON),以便您可以:
a)更轻松地传输它
b)更轻松地存储和恢复它
c)由于每个人都知道格式的定义方式,任何其他程序也可以读取您的对象。
因此,将对象放入数据库只是另一种序列化形式。
反序列化意味着可以从保存的位置再次加载/还原该对象。

1

序列化通常是将运行时对象的状态写入磁盘(但可以是任何地方),并能够再次读取的过程。

有效地,将对象的属性存储到表中是一种序列化形式。

在.NET中,还有其他形式:

  • XmlSerialization
  • BinarySerialization

您也可以自己创建。

但总的来说,如果您正在将对象的状态保存在某个地方,然后将其重新读取到运行时中的“活动”对象中,则正在对其进行序列化。


2
序列化并不一定意味着将其写入磁盘。它只是指将其放入某些可以导出的二进制格式中。例如,序列化对象可能会通过网络发送而不是写入磁盘。 - Chuck
是的,这就是为什么在底部我写了“某处”的原因。我只是在第一句话中漏掉了“通常”。当然,你是正确的。 - Noon Silk

0

序列化

序列化是将一个对象或一组对象图转换为流的过程。

反序列化

反序列化是将流转换回对象或一组对象图的过程。

以下是一些自定义属性:

[OnDeserialization] -> 当我们需要在流的反序列化期间执行某些操作时使用。 [OnDeserialized] -> 当我们需要在将流反序列化为对象后执行某些操作时使用,例如正确设置对象的字段值。

以下是示例

[Serializable]
internal class DemoForSerializableAndDeserializable
{
    internal string Fname = string.Empty;
    internal string Lname = string.Empty;
    
    internal Stream SerializeToMS(DemoForSerializableAndDeserializable objDemo)
    {
        DemoForSerializableAndDeserializable objSer = new DemoForSerializableAndDeserializable();
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(ms, objSer);
        return ms;
    }
    
    [OnDeserializing]
    private void OnDeserializing(StreamingContext context)
    {
        // Do some work while deserializing the stream
    }

    [OnDeserialized]
    private void OnSerialized(StreamingContext context)
    {
        Fname = "abc";
    }
    
}

调用代码

class CallingCode
{
    string fname = string.Empty;
    string Lname = string.Empty; 
           
    static void Main(string[] args)
    {
        DemoForSerializableAndDeserializable demo = new DemoForSerializableAndDeserializable();
    
        Stream ms = demo.SerializeToMS(demo);
        ms.Position = 0;
    
        DemoForSerializableAndDeserializable demo1 = new BinaryFormatter().Deserialize(ms) as DemoForSerializableAndDeserializable;
    
        Console.WriteLine(demo1.Fname);
        Console.WriteLine(demo1.Lname);
        Console.ReadLine();
    }  
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接