42. C# -- 序列化和反序列化

1. 对象序列化的介绍

(1) .NET支持对象序列化的几种方式

(2) 几种序列化的区别

(3) 使用特性对序列化的控制

2. 使用二进制序列化和反序列化

(1) 二进制序列化与反序列化的程序示例

(2) 总结

3. 使用SOAP方式序列化和反序列化

(1) SOAP序列化与反序列化的程序示例

(2) 总结

4. 使用XML方式序列化和反序列化

(1) XML序列化与反序列化的程序示例

(2) 总结

5. XML序列化对象详解

(1) 说明

(2) 使用XmlElement(默认值)

(3) 使用XmlAttribute

(4) 使用XmlText

(5) 使用XmlType和XmlAttribute(重命名节点名称)

(6) 列表和数组的序列化

(7) 列表和数组的做为数据成员的序列化

(8) 类型继承与反序列化

(9) 排除不需要序列化的成员

(10) 强制指定成员的序列化顺序

(11) 自定义序列化行为

(12) 序列化设置XML命名空间

(13) XML的使用建议

(14) 反序列化的使用总结

6. 自定义序列化(仅适用于二进制与SOAP)

(1) 自定义序列化的实现方式

(2) 示例程序

1.对象序列化的介绍

(1).NET支持对象序列化的几种方式

二进制序列化:对象序列化之后是二进制形式的,通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下。

SOAP序列化:对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP 协议传输,通过System.Runtime.Serialization.Formatters.Soap命名空间下的SoapFormatter类来实现的。

XML序列化:对象序列化之后的结果是XML形式的,通过XmlSerializer 类来实现的,这个类位于System.Xml.Serialization命名空间下。XML序列化不能序列化私有数据。

(2)几种序列化的区别

二进制格式和SOAP格式可序列化一个类型的所有可序列化字段,不管它是公共字段还是私有字段。XML格式仅能序列化公共字段或拥有公共属性的私有字段,未通过属性公开的私有字段将被忽略。

使用二进制格式序列化时,它不仅是将对象的字段数据进行持久化,也持久化每个类型的完全限定名称和定义程序集的完整名称(包括包称、版本、公钥标记、区域性),这些数据使得在进行二进制格式反序列化时亦会进行类型检查。SOAP格式序列化通过使用XML命名空间来持久化原始程序集信息。而XML格式序列化不会保存完整的类型名称或程序集信息。这便利XML数据表现形式更有终端开放性。如果希望尽可能延伸持久化对象图的使用范围时,SOAP格式和XML格式是理想选择。

(3)使用特性对序列化的控制

要让一个对象支持.Net序列化服务,用户必须为每一个关联的类加上[Serializable]特性。如果类中有些成员不适合参与序列化(比如:密码字段),可以在这些域前加上[NonSerialized]特性。

2.使用二进制序列化和反序列化

(1)二进制序列化与反序列化的程序示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
    [Serializable]  //必须添加序列化特性
    public class Person
{
        private string Name;//姓名
        private bool Sex;//性别,是否是男
        public Person(string name, bool sex)
{
            this.Name = name;
            this.Sex = sex;
}
        public override string ToString()
{
            return "name:" + this.Name + "\tsex:" + (this.Sex ? "Male" : "Female");
}
}
    [Serializable]  //必须添加序列化特性
    public class Programmer : Person
{
        private string Language;//编程语言
        public Programmer(string name, bool sex, string language)
            : base(name, sex)
{
            this.Language = language;
}
        public override string ToString()
{
            return base.ToString() + "\tprogram language:" + this.Language;
}
}
    class Program
{
        static void Main(string[] args)
{
            //创建Programmer列表,并添加对象
            List<Programmer> list = new List<Programmer>();
            list.Add(new Programmer("Li zhiwei", true, "C#"));
            list.Add(new Programmer("Coder2", false, "C++"));
            list.Add(new Programmer("Coder3", true, "Java"));
            //使用二进制序列化对象
            string fileName = @"e:\Programmers.dat";//文件名称与路径
            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
binFormat.Serialize(fStream, list);
            //使用二进制反序列化对象
            list.Clear();//清空列表
            fStream.Position = 0;//重置流位置
            list = (List<Programmer>)binFormat.Deserialize(fStream);//反序列化对象
            foreach (Programmer p in list)
{
                Console.WriteLine(p);
}
            Console.Read();
}
}
}

结果:

(2)总结

使用二进制序列化,必须为每一个要序列化的的类和其关联的类加上[Serializable]特性,对类中不需要序列化的成员可以使用[NonSerialized]特性。

二进制序列化对象时,能序列化类的所有成员(包括私有的),且不需要类有无参数的构造方法。

使用二进制格式序列化时,它不仅是将对象的字段数据进行持久化,也持久化每个类型的完全限定名称和定义程序集的完整名称(包括包称、版本、公钥标记、区域性),这些数据使得在进行二进制格式反序列化时亦会进行类型检查。所以反序列化时的运行环境要与序列化时的运行环境要相同,否者可能会无法反序列化成功。

3.使用SOAP方式序列化和反序列化

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
// Note: When building this code, you must reference the
// System.Runtime.Serialization.Formatters.Soap.dll assembly.
using System.Runtime.Serialization.Formatters.Soap;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
    [Serializable]  //必须添加序列化特性
    public class Person
{
        private string Name;//姓名
        private bool Sex;//性别,是否是男
        public Person(string name, bool sex)
{
            this.Name = name;
            this.Sex = sex;
}
        public override string ToString()
{
            return "name:" + this.Name + "\tsex:" + (this.Sex ? "Male" : "Female");
}
}
    [Serializable]  //必须添加序列化特性
    public class Programmer : Person
{
        private string Language;//编程语言
        public Programmer(string name, bool sex, string language)
            : base(name, sex)
{
            this.Language = language;
}
        public override string ToString()
{
            return base.ToString() + "\tprogram language:" + this.Language;
}
}
    class Program
{
        static void Main(string[] args)
{
            //实例化对象
            Programmer p = new Programmer("Li zhiwei", true, "C,C#,C++,Java");
            //使用SOAP序列化对象
            string fileName = @"e:\Programmers.xml";//文件名称与路径
            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            SoapFormatter soapFormat = new SoapFormatter();//创建SOAP序列化器
            soapFormat.Serialize(fStream, p);//SOAP不能序列化泛型对象
            //使用SOAP反序列化对象
            fStream.Position = 0;//重置流位置
            p = null;
            p = (Programmer)soapFormat.Deserialize(fStream);
            Console.WriteLine(p);
            Console.Read();
}
}
}

结果:

(2)总结

SOAP序列化与二进制序列化的区别是:SOAP序列化不能序列化泛型类型。与二进制序列化一样在序列化时不需要向序列化器指定序列化对象的类型。而XML序列化需要向XML序列化器指定序列化对象的类型。

4.使用XML方式序列化和反序列化

(1)XML序列化与反序列化的程序示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
    public class Person
{
        public string Name;//姓名
        public bool Sex;//性别,是否是男
        public Person() { }//必须提供无参构造器,否则XmlSerializer将出错
        public Person(string name, bool sex)
{
            this.Name = name;
            this.Sex = sex;
}
        public override string ToString()
{
            return "name:" + this.Name + "\tsex:" + (this.Sex ? "Male" : "Female");
}
}
    public class Programmer : Person
{
        public  string Language;//编程语言
        public Programmer() { }//必须提供无参构造器,否则XmlSerializer将出错
        public Programmer(string name, bool sex, string language)
            : base(name, sex)
{
            this.Language = language;
}
        public override string ToString()
{
            return base.ToString() + "\tprogram language:" + this.Language;
}
}
    class Program
{
        static void Main(string[] args)
{
            //创建Programmer列表,并添加对象
            List<Programmer> list = new List<Programmer>();
            list.Add(new Programmer("Li zhi wei", true, "C#"));
            list.Add(new Programmer("Coder2", false, "C++"));
            list.Add(new Programmer("Coder3", true, "Java"));
            //使用XML序列化对象
            string fileName = @"e:\Programmers.xml";//文件名称与路径
            Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>),new Type[] { typeof(Programmer), typeof(Person) });//创建XML序列化器,需要指定对象的类型
xmlFormat.Serialize(fStream, list);
            //使用XML反序列化对象
            fStream.Position = 0;//重置流位置
list.Clear();
            list = (List<Programmer>)xmlFormat.Deserialize(fStream);
            foreach (Programmer p in list)
{
                Console.WriteLine(p);
}
            Console.Read();
 
}
}
}

结果:

(2)总结

使用XML序列化或反序列化时,需要对XML序列化器指定需要序列化对象的类型和其关联的类型。

XML序列化只能序列化对象的公有属性,并且要求对象有一个无参的构造方法,否者无法反序列化。

[Serializable]和[NonSerialized]特性对XML序列化无效!所以使用XML序列化时不需要对对象增加[Serializable]特性。

5.XML序列化对象详解

(1)说明

本节主要介绍:使用特性控制对象序列化成XML文件的格式。

(2)使用XmlElement(默认值)

类声明:

public class Person

{

[XmlElement]

public string Name;//使用[XmlElement]特性

public bool Sex;//默认使用了[XmlElement]特性

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

<Name>李志伟</Name>

<Sex>true</Sex>

</Person>

(3)使用XmlAttribute

类声明:

public class Person

{

[XmlElement]

public string Name;

[XmlAttribute]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">

<Name>李志伟</Name>

</Person>

(4)使用XmlText

类声明:

public class Person

{

[XmlText]

public string Name;

[XmlAttribute]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">李志伟</Person>

(5)使用XmlType和XmlAttribute(重命名节点名称)

类声明:

[XmlType("个人信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

序列化生成的XML文件:

<个人信息xmlns:xsi="..."xmlns:xsd="..."姓名="李志伟"性别="true" />

(6)列表和数组的序列化

类声明:

[XmlType("个人信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

class Program

{

static void Main(string[] args)

{

Person p = new Person();

p.Name = "李志伟";

p.Sex = true;

Person[] ps = new Person[3];

ps[0] = p;

ps[1] = p;

ps[2] = p;

//使用XML序列化对象

string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名称与路径

Stream fStream = new FileStream(fileName, FileMode.Create);

XmlSerializer xmlFormat = new XmlSerializer(typeof(Person[]));

xmlFormat.Serialize(fStream, ps);//序列化对象

fStream.Dispose();//关闭文件

Console.WriteLine("OK!");

Console.Read();

}

}

序列化生成的XML文件:

<ArrayOf个人信息xmlns:xsi="..."xmlns:xsd="...">

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

</ArrayOf个人信息>

注意:发现此时的XML文件的根节点名称变了。此时要重命名根节点应使用如下方式:

[XmlType("个人信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

[XmlType("人员信息")]

public class PersonArray : List<Person> { }

class Program

{

static void Main(string[] args)

{

Person p = new Person();

p.Name = "李志伟";

p.Sex = true;

PersonArray ps = new PersonArray();

ps.Add(p);

ps.Add(p);

ps.Add(p);

//使用XML序列化对象

string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名称与路径

Stream fStream = new FileStream(fileName, FileMode.Create);

XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

xmlFormat.Serialize(fStream, ps);//序列化对象

fStream.Dispose();//关闭文件

Console.WriteLine("OK!");

Console.Read();

}

}

序列化生成的XML文件:

<人员信息xmlns:xsi="..."xmlns:xsd="...">

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

</人员信息>

(7)列表和数组的做为数据成员的序列化

类声明:

[XmlType("信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

public class PersonArray

{

public List<Person> Array=new List<Person>();

public Person Person = new Person();

}

class Program

{

static void Main(string[] args)

{

PersonArray ps = new PersonArray();

ps.Person = new Person();

ps.Person.Name = "李志伟";

ps.Person.Sex = true;

ps.Array.Add(ps.Person);

ps.Array.Add(ps.Person);

ps.Array.Add(ps.Person);

//使用XML序列化对象

string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名称与路径

Stream fStream = new FileStream(fileName, FileMode.Create);

XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

xmlFormat.Serialize(fStream, ps);//序列化对象

fStream.Dispose();//关闭文件

Console.WriteLine("OK!");

Console.Read();

}

}

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

<Array>

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

</Array>

<Person姓名="李志伟"性别="true" />

</PersonArray>

注意:假设这里需要为Array和Person的节点重命名,代码如下:

[XmlType("信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

public class PersonArray

{

[XmlArrayItem("个人信息")]

[XmlArray("人员信息")]

public List<Person> Array=new List<Person>();

public Person Person = new Person();

}

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

<人员信息>

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

</人员信息>

<Person姓名="李志伟"性别="true" />

</PersonArray>

注意:把“人员信息”节点去掉呢(直接出现“个人信息”节点)

[XmlType("信息")]

public class Person

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

public class PersonArray

{

[XmlElement("个人信息")]

public List<Person> Array=new List<Person>();

public Person Person = new Person();

}

序列化生成的XML文件:

<PersonArrayxmlns:xsi="..."xmlns:xsd="...">

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<个人信息姓名="李志伟"性别="true" />

<Person姓名="李志伟"性别="true" />

</PersonArray>

(8)类型继承与反序列化

类声明:

public class Base { }

[XmlType("信息A")]

public class PersonA : Base

{

[XmlAttribute("姓名")]

public string Name;

[XmlAttribute("性别")]

public bool Sex;

public PersonA() { }//必须提供无参构造器,否则XmlSerializer将出错

}

[XmlType("信息B")]

public class PersonB : Base

{

[XmlElement("姓名")]

public string Name;

[XmlElement("年龄")]

public int Age;

public PersonB() { }//必须提供无参构造器,否则XmlSerializer将出错

}

[XmlType("人员信息")]

public class PersonArray

{

[XmlArrayItem(typeof(PersonA)), XmlArrayItem(typeof(PersonB))]

public List<Base> ListPerson=new List<Base>();

}

class Program

{

static void Main(string[] args)

{

PersonA pa = new PersonA();

pa.Name = "李志伟A";

pa.Sex = true;

PersonB pb = new PersonB();

pb.Name = "李志伟B";

pb.Age = 21;

PersonArray ps = new PersonArray();

ps.ListPerson.Add(pa);

ps.ListPerson.Add(pa);

ps.ListPerson.Add(pb);

ps.ListPerson.Add(pb);

//使用XML序列化对象

string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名称与路径

Stream fStream = new FileStream(fileName, FileMode.Create);

XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));

xmlFormat.Serialize(fStream, ps);//序列化对象

fStream.Dispose();//关闭文件

Console.WriteLine("OK!");

Console.Read();

}

}

序列化生成的XML文件:

<人员信息xmlns:xsi="..."xmlns:xsd="...">

<ListPerson>

<信息A姓名="李志伟A"性别="true" />

<信息A姓名="李志伟A"性别="true" />

<信息B>

<姓名>李志伟B</姓名>

<年龄>21</年龄>

</信息B>

<信息B>

<姓名>李志伟B</姓名>

<年龄>21</年龄>

</信息B>

</ListPerson>

</人员信息>

注意:同时为列表成员指定多个[XmlArrayItem(typeof(XXX))]可实现多种派生类型混在一起输出。

(9)排除不需要序列化的成员

类声明:

public class Person

{

public string Name;

[XmlIgnore]// 这个属性将不会参与序列化

public bool Sex;

public Person() { }

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

<Name>李志伟</Name>

</Person>

(10)强制指定成员的序列化顺序

类声明:

public class Person

{

[XmlElement(Order = 2)]

public string Name;

[XmlElement(Order = 1)]

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="...">

<Sex>true</Sex>

<Name>李志伟</Name>

</Person>

(11)自定义序列化行为

类声明:

public class Person : IXmlSerializable

{

public string Name;

public bool Sex;

public Person() { }//必须提供无参构造器,否则XmlSerializer将出错

public System.Xml.Schema.XmlSchema GetSchema()

{

return null;

}

public void ReadXml(System.Xml.XmlReader reader)

{

Name = reader.GetAttribute("姓名");

Sex = reader.GetAttribute("性别").Equals("男") ? true : false;

}

public void WriteXml(System.Xml.XmlWriter writer)

{

writer.WriteAttributeString("姓名", Name);

writer.WriteAttributeString("性别", Sex ? "男" : "女");

}

}

序列化生成的XML文件:

<Person姓名="李志伟"性别="男" />

(12)序列化设置XML命名空间

类声明:

[XmlRoot(Namespace = "http://msdn.microsoft.com/vsdh.xsd")]

public class Person

{

public string Name;

public bool Sex;

public Person() { }

}

序列化生成的XML文件:

<Personxmlns:xsi="..."xmlns:xsd="..."xmlns="http://msdn.microsoft.com/vsdh.xsd">

<Name>李志伟A</Name>

<Sex>true</Sex>

</Person>

(13)XML的使用建议

在服务端,C#代码中:

1. 建议不用使用低级别的XML API来使用XML,除非你是在设计框架或者通用类库。

2. 建议使用序列化、反序列化的方法来生成或者读取XML

3. 当需要考虑使用XML时,先不要想着XML结构,先应该定义好数据类型。

4. 列表节点不要使用[XmlElement],它会让所有子节点【升级】,显得结构混乱。

5. 如果希望序列化的XML长度小一点,可以采用[XmlAttribute],或者指定一个更短小的别名。

6. 不要在一个列表中输出不同的数据类型,这样的XML结构的可读性不好。

7. 尽量使用UTF-8编码,不要使用GB2312编码。

在客户端,JavaScript代码中,我不建议使用XML,而是建议使用JSON来代替XML,因为:

1. XML文本的长度比JSON要长,会占用更多的网络传输时间(毕竟数据保存在服务端,所以传输是免不了的)。

2. 在JavaScritp中使用XML比较麻烦(还有浏览器的兼容问题),反而各种浏览器对JSON有非常好的支持。

(14)反序列化的使用总结

如果XML是由类型序列化得到那的,那么反序列化的调用代码是很简单的,反之,如果要面对一个没有类型的XML,就需要我们先设计一个(或者一些)类型出来,这是一个逆向推导的过程,请参考以下步骤:

1. 首先要分析整个XML结构,定义与之匹配的类型,

2. 如果XML结构有嵌套层次,则需要定义多个类型与之匹配,

3. 定义具体类型(一个层级下的XML结构)时,请参考以下表格。

6.自定义序列化(仅适用于二进制与SOAP)

(1)自定义序列化的实现方式

可以通过在对象上实现 ISerializable 接口来自定义序列化过程。这一功能在反序列化后成员变量的值失效时尤其有用,但是需要为变量提供值以重建对象的完整状态。要实现ISerializable,需要实现 GetObjectData()方法以及一个特殊的构造函数,在反序列化对象时要用到此构造函数。

(2)示例程序

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
    [Serializable]
    public class Person : ISerializable
{
        public string Name;
        public bool Sex;
        public Person() { }
        //必须的够着方法,反序列化时调用
        protected Person(SerializationInfo info, StreamingContext context)
{
            Name = info.GetString("name");
            Sex = info.GetBoolean("sex");
}
        //序列化时调用
        public void GetObjectData(SerializationInfo info, StreamingContext context)
{
            info.AddValue("name", Name + "(User defined Serialization)");
            info.AddValue("sex", Sex);
}
        public override string ToString()
{
            return "name:" + this.Name + "\tsex:" + (this.Sex ? "Male" : "Female");
}
}
    class Program
{
        static void Main(string[] args)
{
            Person p = new Person();
            p.Name = "Li zhi wei";
            p.Sex = true;
            //使用二进制序列化对象
            string fileName = @"e:\Programmers.xml";//文件名称与路径
            Stream fStream = new FileStream(fileName, FileMode.Create);
            BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
            binFormat.Serialize(fStream, p);//序列化对象
            //使用二进制反序列化对象
            fStream.Position = 0;//重置流位置
            p = (Person)binFormat.Deserialize(fStream);//反序列化对象
            Console.WriteLine(p);
            fStream.Dispose();//关闭文件
            Console.WriteLine("OK!");
            Console.Read();
}
}
}

结果:

注意:在序列化过程中调用 GetObjectData()时,需要填充方法调用中提供的SerializationInfo对象。只需按名称/值对的形式添加将要序列化的变量。其名称可以是任何文本。只要已序列化的数据足以在反序列化过程中还原对象,便可以自由选择添加至SerializationInfo 的成员变量。如果基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData()方法。同样,在反序列化时也会调用含有(SerializationInfo info, StreamingContextcontext)参数的特殊的够着方法!否者将无法反序列化!!!

参考:
http://www.cnblogs.com/yzenet/p/3622833.html

时间: 2024-08-10 02:06:15

42. C# -- 序列化和反序列化的相关文章

序列化与反序列化总结(Serializable和Parcelable)

序列化是指将对象的状态信息转换为可以存储或传输的形式的过程. 在Java中创建的对象,只要没有被回收就可以被复用,但是,创建的这些对象都是存在于JVM的堆内存中,JVM处于运行状态时候,这些对象可以复用, 但是一旦JVM停止,这些对象的状态也就丢失了. 在实际生活中,需要将对象持久化,需要的时候再重新读取出来,通过对象序列化,可以将对象的状态保存为字节数组,需要的时候再将字节数组反序列化为对象. 对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间转换,广泛用于RMI(远程方法调用)以

java 21 - 13 IO流之序列化和反序列化

序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输.对象 -- 流数据(ObjectOutputStream) 构造方法:ObjectInputStream(InputStream in)  创建从指定 InputStream 读取的 ObjectInputStream 反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象.流数据 -- 对象(ObjectInputStream) 构造方法:ObjectInputStream(InputStream in)  创建从指定

【转】Java对象序列化和反序列化

[转自]孤傲苍狼的Java基础学习总结——Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对 象,当有 10万用户并发访问,就有可

.net学习笔记--序列化与反序列化

序列化其实就是将一个对象的所有相关的数据保存为一个二进制文件(注意:是一个对象) 而且与这个对象相关的所有类型都必须是可序列化的所以要在相关类中加上 [Serializable]特性 对象类型包括:对象本神包含的类型,父类 拥有需要的对象之后:1.将对象转换为二进制数据 使用专门的对像进行转换 BinaryFormatter 2.将二进制数据写入到文件 FileSteam 反序列化则是把二进制文件转换为一个对象 例子代码如下: 1 using System; 2 using System.Col

Java对象的serialVersion序列化和反序列化

Java基础学习总结——Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Ses

20151024_004_C#基础知识(C#中的访问修饰符,继承,new关键字,里氏转换,is 和 as,多态,序列化与反序列化)

1:C#中的访问修饰符 public: 公共成员,完全公开,没有访问限制. private: 私有的,只能在当前类的内部访问. protected: 受保护的,只能在当前类的内部以及该类的子类中访问. internal: 只能在当前项目中访问,在同一个项目中,internal和public的权限是一样的. protected internal: protected + internal权限. 1.1:能够修饰类的访问修饰符只有两个: public / internal 1.2:接口中的成员不允许

Java对象的序列化和反序列化(转)

一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些s

Java基础学习总结——Java对象的序列化和反序列化

一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些s

python基础之继承组合应用、对象序列化和反序列化,选课系统综合示例

继承+组合应用示例 1 class Date: #定义时间类,包含姓名.年.月.日,用于返回生日 2 def __init__(self,name,year,mon,day): 3 self.name = name 4 self.year=year 5 self.mon=mon 6 self.day=day 7 def tell_birth(self): 8 print('%s:%s-%s-%s'%(self.name,self.year,self.mon,self.day)) 9 10 11