序列化、反序列化的版本控制以及序列化、反序列化集合对象
2023-09-11 14:16:44 时间
当涉及到跨进程甚至是跨域传输数据的时候,我们需要把对象序列化和反序列化。
首先可以使用Serializable特性。
[Serializable]
public class Person
{
public string _firstName;
public string _secondName;
//序列化
[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
_firstName = _firstName.ToUpper();
_secondName = _secondName.ToUpper();
}
//反序列化
[OnDeserialized]
internal void OnDeserialized(StreamingContext context)
{
_firstName = _firstName.ToLower();
_secondName = _secondName.ToLower();
}
}
当然,也可以实现ISerializable接口。在接口方法GetObjectData完成序列化,把信息保存到SerializationInfo中,在构造函数中反序列化,把信息从SerializationInfo中读取出来。
[Serializable]
public class Person : ISerializable
{
public string _firstName;
public string _secondName;
public Person()
{
}
//反序列化
public Person(SerializationInfo si, StreamingContext context)
{
_firstName = si.GetString("first").ToLower();
_secondName = si.GetString("second").ToLower();
}
//序列化
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("first", _firstName.ToUpper());
info.AddValue("second",_secondName.ToUpper());
}
}
对序列化和反序列化对象进行版本控制
下面的类,描述了对象的第一个版本。
[Serializable]
public class SomeClass : ISerializable
{
private int a;
public SomeClass(){}
public SomeClass(SerializationInfo info, StreamingContext context)
{
a = info.GetInt32("myval");
}
public void GetObjectData(SerializationInfo, StreamingContext context)
{
info.AddValue("VERSION",1);
info.AddValue("myval", a);
}
}
现在SomeClass要增加一个私有字段,成为版本二。
[Serializable]
public class SomeClass : ISerializable
{
private int a;
private string b;
public SomeClass(){}
public SomeClass(SerializationInfo info, StreamingContext context)
{
int VERSION = info.GetInt32("VERSION");
a = info.GetInt32("a");
if(VERSION > 1)
{
b = info.GetString("another");
}
else
{
b = "默认值";
}
}
public void GetObjectData(SerializationInfo, StreamingContext context)
{
info.AddValue("VERSION",2);
info.AddValue("myval", a);
info.AddValue("another", b);
}
}
把集合对象序列化到文件并反序列化读出
如果一个集合对象需要实现序列化和反序列化,那么集合元素对象必须可以被序列化和反序列化,并且集合元素对象中的对象属性也必须可以被序列化和反序列化,依此类推。
[Serializable]
public class Car : ISerializable
{
private string _model;
private int _year;
private Owner _owner;
public Car()
{
}
public Car(SerializationInfo info, StreamingContext context)
{
this._model = (string) info.GetValue("Model", typeof (string));
this._year = (int) info.GetValue("Year", typeof (int));
this._owner = (Owner) info.GetValue("Owner", typeof (Owner));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Model",this._model);
info.AddValue("Year", this._year);
info.AddValue("Owner", this._owner);
}
}
[Serializable]
public class Owner : ISerializable
{
private string _name;
public Owner()
{
}
public Owner(SerializationInfo info, StreamingContext context)
{
this._name = (string) info.GetValue("Name", typeof (string));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", this._name);
}
}
以上,我们想序列化Car的集合到文件中,再反序列化Cars的集合读取出来。那么,我们必须让Car可以被序列化和反序列化,Car的属性对象Owner也必须可以被序列化和反序列化。
接着,用来封装Car集合的一个类。
[Serializable]
public class CarsList : ISerializable
{
private List<Car> _cars;
public List<Car> Cars
{
get { return this._cars; }
set { this._cars = value; }
}
public CarsList()
{
}
public CarsList(SerializationInfo info, StreamingContext context)
{
this._cars = (List<Car>) info.GetValue("Cars", typeof (List<Car>));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Cars", this._cars);
}
}
针对CarsList写一个序列化和反序列化的帮助类。
public class SerializerHelper
{
public SerializerHelper()
{
}
//序列化
public void SerializeObject(string fileName, CarsList carsList)
{
//根据文件名打开流
Stream stream = File.Open(fileName, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
//把对象序列化到流中
bFormatter.Serialize(stream,carsList);
stream.Close();
}
//反序列化
public CarsList DeserializeObject(string fileName)
{
CarsList carsList;
//根据文件名打开流
Stream stream = File.Open(fileName, FileMode.Open);
BinaryFormatter bfFormatter = new BinaryFormatter();
carsList = (CarsList)bfFormatter.Deserialize(stream);
stream.Close();
return carsList;
}
}
在客户端按如下调用:
static void Main(string[] args)
{
List<Car> cars = new List<Car>();
CarsList carsList = new CarsList();
carsList.Cars = cars;
SerializerHelper serializerHelper = new SerializerHelper();
serializerHelper.SerializeObject(@"temp.txt", carsList);
carsList = serializerHelper.DeserializeObject(@"temp.txt");
cars = carsList.Cars;
}
相关文章
- ASP.NET MVC之表单集合数据自动绑定到对象属性(集合)中
- POJ 1201 差分约束(集合最小元素个数)
- 集合框架体系结构图
- 第一节: Timer的定时任务的复习、Quartz.Net的入门使用、Aop思想的体现 第十九节: 结合【表达式目录树】来封装EF的BaseDal层的方法 第二十节: 深入理解并发机制以及解决方案(锁机制、EF自有机制、队列模式等) 框架搭建篇 第二十一节:ADO层次上的海量数据处理方案(SqlBulkCopy类插入和更新) 第十四节: 介绍四大并发集合类并结合单例模式下的队列来说明线程
- 数组跟集合的差别
- MongoDB文档和集合
- 了解集合本质必须要知晓的概念04-二叉查找树
- 【Analytics Kit】【FAQ】集成华为分析服务问题集合 SDK初始化失败/应用调试界面没有数据/常见错误提示
- Eclipse优化集合,Eclipse优化速度,解决Ctrl+C、Ctrl+V卡
- 大数据学习——scala集合练习
- java8List集合根据对象的属性去重
- java jdk8 使用stream实现两个list集合合并成一个list集合(对象属性的合并)