序列化主要用在数据持久化和远程调用
序列化和反序列化我们可能经常会听到,其实通俗一点的解释,序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用。
我想最主要的作用有:
1 、在进程下次启动时读取上次保存的对象的信息
2 、在不同的AppDomain 或进程之间传递数据
3 、在分布式应用系统中传递数据
来源参考:http://blog.163.com/szx_rencaijob/blog/static/3844710820092190758797/
提问人的追问 2009-06-11 16:50
能通俗点解释不
回答人的补充 2009-06-11 16:52
再通俗点就是序列化把对象转换成另一种格式(比如2 进制文件,xml 文件等)。
提问人的追问 2009-06-11 16:53
那对象一般是什么?
回答人的补充 2009-06-11 16:56
.net 是面相对象编程,广义的将,你在那里用的所有东西都叫“ 对象” 。
提问人的追问 2009-06-11 16:57
那么,一般用于这种序列化是用在什么方面,举个例子一下,谢谢。
回答人的补充 2009-06-11 17:00
比如论坛这个对象,有论坛名称,论坛地址等属性,可以把这些东西全部序列化到xml 里,需要使用的时候,反序列化成论坛对象本身,读出对应属性即可。
提问人的追问 2009-06-11 17:01
具体是用到项目中的哪些模块,就是说一般来说是用来做什么的。在网站中?
回答人的补充 2009-06-11 17:02
灵活使用,就跟response 这个对象一样,谁能说清楚是哪个模块用的多呢
提问人的追问 2009-06-11 17:04
哦,了解了,大致上清楚了,谢谢。
把对象状态保存到流中,达到持久化(或远程调用)的作用,
比如你有一个类有 100 个属性字段,如果在其他地方使用这个被实例化的类就必须读取 100 次它的属性以获取对象的状态信息,
才能利用这些信息构建新类。
有了序列化你将类信息保存到一个流比如 xml 中,但要构造新类时候直接反序列化,将所有属性直接付给新实例。这比你手工写代码读取属性方便,还实现了持久化。
可以方便的把你的数据 “ 拿走 ” 。
比如我以前有一个项目,公司内部人员在内网给一个 B/S 系统添加了点数据,经过审查后这些数据要放到外部网站上去,不能再去网站上添一次吧,所以就要把这些数据序列化,然后通过 WebService 传过去。
序列化:将自己的类保存成某种格式。可以保存为文件,或在网络上传输。
反序列:将数据还原成类。
作用:随心所欲,想怎么用就怎么用。
序列化就是把多个对象相关的数据按一定方式组织起来,便于传输或存储,以备后来的数据恢复。
将一个对象序列化之后,得到一个数据序列,将此数据序列通过任何方式传递到另一进程,就可以使用反序列化操作重新构建这个对象的拷贝 .
任何进程间过程调用,都需要将对象数据进行序列化,然后到另一进程空间进行反序列化,所以这是跨进程过程调用的重要操作
收录一:
我的理解:
比如用一个类描述一张合同,而这个类实例化后其中的字段保存着合同的信息,如果现在要把这个类的实例发送到另一台机器、另一个窗体或是想保存这个类以便以 后再取出来用(持久化对象),可以对这个类进行序列化(序列化实际上是一个信息流),传送或保存,用的时候再反序列化重新生成这个对象
为什么您想要使用序列化?有两个最重要的原因促使对序列化的使用:一个原因是将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本;另 一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,序列化可用于在 ASP.NET 中保存会话状态并将对象复制到 Windows 窗体的剪贴板中。远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中。
序列化的是对象的状态
也就是对象数据成员的值和方法是没有关系的
跨应用程序域通信时,要用到序列化
以及用WEB 服务时
一:BinaryFormatter 序列化
序列化简单点来理解就是把内存的东西写到硬盘中, 当然也可以写到内存中( 这个内容我会在后面写一个例子). 而反序列化就是从硬盘中把信息读到内存中. 就这么简单, 呵呵, 现在来看下面的例子吧!
在这篇文章中我将使用BinaryFormatter 序列化类Book 作为例子, 希望大家能从例子中深刻体会什么是序列化.
定义类Book:
[Serializable]
public Class Book
{
string name;
float price;
string author;
public Book(string bookname, float bookprice, string bookauthor)
{
name = bookname;
price = bookprice;
author = bookauthor;
}
}
在类的上面增加了属性:Serializable.( 如果不加这个属性, 将抛出SerializationException 异常).
通过这个属性将Book 标志为可以序列化的. 当然也有另一种方式使类Book 可以序列化, 那就是实行ISerializable 接口了. 在这里大家要注意了:Serializable 属性是不能被继承的咯!!!
如果你不想序列化某个变量, 该怎么处理呢? 很简单, 在其前面加上属性[NonSerialized] . 比如我不想序列化
string author;
那我只需要
[NonSerialized]
string author;
好了, 现在就告诉大家怎么实现序列化:
我们使用namespace:
using System;
using System.IO;
using System.RunTime.Serialization.Formatters.Binary;
首先创建Book 实例,like this:
Book book = new Book("Day and Night", Numbertype="1" tcsc="0">30.0f, "Bruce");
接着当然要创建一个文件了, 这个文件就是用来存放我们要序列化的信息了.
FileStream fs = new FileStream(@"C:\book.dat", FileMode.Create);
序列化的实现也很简单,like this:
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, book);
很简单吧! 现在我列出整个原代码, 包括反序列化.
static void Main(string[] args)
{
Book book = new Book("Day and Night", 30.0f, "Bruce");
using(FileStream fs = new FileStream(@"C:\book.dat", FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, book);
}
book = null;
using(FileStream fs = new FileStream(@"C:\book.dat", FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
book = (Book)formatter.Deserialize(fs);// 在这里大家要注意咯, 他的返回值是object
}
}
有不对的地方, 请大家多多纠正.....
注意一定不要忘了: using System.Runtime.Serialization.Formatters.Binary;
命名空间。
收录二:
原先一直用BinaryFormatter 来序列化挺好,可是最近发现在WinCE 下是没有办法进行BinaryFormatter 操作,很不爽, 只能改成了BinaryWriter 和BinaryReader 来读写,突然想到能不能用XML 来序列化?于是在网上查了些资料便写了些实践性代码,做些 记录,避免以后忘记。
序列化对象
public class People
{
[XmlAttribute("NAME")]
public string Name
{ set; get; }
[XmlAttribute("AGE")]
public int Age
{ set; get; }
}
[XmlRoot("Root")]
public class Student : People
{
[XmlElement("CLASS")]
public string Class
{ set; get; }
[XmlElement("NUMBER")]
public int Number
{ set; get; }
}
void Main(string[] args)
{
Student stu = new Student()
{
Age = 10,
Class = "Class One",
Name = "Tom",
Number = 1
};
XmlSerializer ser = new XmlSerializer(typeof(Student));
ser.Serialize(File.Create("C:\\x.xml"), stu);
}
反序列化对象
XmlSerializer ser = new XmlSerializer(typeof(Student));
Student stu = ser.Deserialize(File.OpenRead("C:\\x.xml")) as Student;
对象数组序列化
public class People
{
[XmlAttribute("NAME")]
public string Name
{ set; get; }
[XmlAttribute("AGE")]
public int Age
{ set; get; }
}
[XmlRoot("Root")]
public class Student : People
{
[XmlElement("CLASS")]
public string Class
{ set; get; }
[XmlElement("NUMBER")]
public int Number
{ set; get; }
}
void Main(string[] args)
{
List<Student> stuList = new List<Student>();
stuList.Add(new Student() { Age = 10, Number = 1, Name = "Tom", Class = "Class One" });
stuList.Add(new Student() { Age = 11, Number = 2, Name = "Jay", Class = "Class Two" });
stuList.Add(new Student() { Age = 12, Number = 3, Name = "Pet", Class = "Class One" });
stuList.Add(new Student() { Age = 13, Number = 4, Name = "May", Class = "Class Three" });
stuList.Add(new Student() { Age = 14, Number = 5, Name = "Soy", Class = "Class Two" });
XmlSerializer ser = new XmlSerializer(typeof(List<Student>));
ser.Serialize(File.Create("C:\\x.xml"), stuList);
}
对象数组反序列
XmlSerializer ser = new XmlSerializer(typeof(List<Student>));
List<Student> stuList = ser.Deserialize(File.OpenRead("C:\\x.xml")) as List<Student>;
foreach (Student s in stuList)
{
MessageBox.Show(string.Format("{0} : {1} : {2} : {3}",
s.Name, s.Age, s.Class, s.Number));
}
序列化Dirctionary
public struct DirectionList
{
[XmlAttribute("Name")]
public string Name;
[XmlElement("Value")]
public int Value;
}
void Main(string[] args)
{
Dictionary<string, int> list = new Dictionary<string, int>();
list.Add("1", 100);
list.Add("2", 200);
list.Add("3", 300);
list.Add("4", 400);
list.Add("5", 500);
list.Add("6", 600);
list.Add("7", 700);
list.Add("8", 800);
list.Add("9", 900);
List<DirectionList> dirList = new List<DirectionList>();
foreach (var s in list)
{
dirList.Add(new DirectionList() { Name = s.Key, Value = s.Value });
}
XmlSerializer ser = new XmlSerializer(typeof(List<DirectionList>));
ser.Serialize(File.Create("C:\\x.xml"), dirList);
}
这里还要讲一点,在XmlSerializer 中,不支持Dirctionary<> 类型的对象,所以在序列化这种最常见类型的时候, 只能按照它的格式先创建一个可以别序列化的类型,这里我定义了一个结构体,当然你也可以定义成其他的类。将Dictionary<> 中的数据 依次放进结构体以后就可以放入流中了。
[XmlAttribute("Name")] 意思是将这个字段作为xml 的属性,属性名跟在“” 中
[XmlElement("Value")] 意思是将这个字段做为xml 的元素。
反序列化Dirctionary
XmlSerializer ser = new XmlSerializer(typeof(List<DirectionList>));
List<DirectionList> dirList = ser.Deserialize(
File.OpenRead("C:\\x.xml")) as List<DirectionList>;
foreach (var v in dirList)
{
Console.WriteLine("{0} : {1}", v.Name, v.Value);
}
其实我并不喜欢这个名称,感觉有点生化危机的feel ,但是也就是这样了,没有太炫的地方,Deserialize 反序列化。真希望.Net 能集成Dirctionary<> 对象,那我们这些懒人就方便了。
在需要序列化的队伍中,数组是很常见的类型,其次就是图片了
序列化图片
public struct ImageStruct
{
[XmlAttribute("Number")]
public int number;
[XmlElement("Image")]
public byte[] picture;
}
void Main(string[] args)
{
ImageStruct s = new ImageStruct() { number = 1, picture = File.ReadAllBytes(@"11.jpg") };
XmlSerializer ser = new XmlSerializer(typeof(ImageStruct));
FileStream fs = File.Create("c:\\x.xml");
ser.Serialize(fs, s);
fs.Close();
}
一样的,采用结构体来保存图片,这里我还加了个图片的名字,到时候查找起来也方便一些
图片反序列化
XmlSerializer ser = new XmlSerializer(typeof(ImageStruct));
ImageStruct s = (ImageStruct)ser.Deserialize(File.OpenRead("c:\\x.xml"));
pictureBox1.Image = Image.FromStream(new MemoryStream(s.picture));
没有花头的方式,利用memorystream 来做缓存,这样会比较快一点,实际上我并没有怎么感觉。
图片数组序列化
public struct ImageStruct
{
[XmlAttribute("Number")]
public int number;
[XmlElement("Image")]
public byte[] picture;
}
void Main(string[] args)
{
List<ImageStruct> imageList = new List<ImageStruct>();
imageList.Add(new ImageStruct()
{
number = 1,
picture = File.ReadAllBytes(@"11.jpg")
});
imageList.Add(new ImageStruct()
{
number = 2,
picture = File.ReadAllBytes(@"22.jpg")
});
XmlSerializer ser = new XmlSerializer(typeof(List<ImageStruct>));
FileStream fs = File.Create("c:\\x.xml");
ser.Serialize(fs, imageList);
fs.Close();
}
图片数组反序列化
XmlSerializer ser = new XmlSerializer(typeof(List<ImageStruct>));
List<ImageStruct> s = (List<ImageStruct>)ser.Deserialize(File.OpenRead("c:\\x.xml"));
var im = from i in s
where i.number == 1
select i.picture;
//var im = s.Where(p => p.number == 1).Select(p => p.picture);
foreach (var image in im)
{
pictureBox1.Image = Image.FromStream(
new MemoryStream(image));
}
这里还对数组结构进行了Linq 查询,这样就可以很方便的查询图片了。
收录三:
序列化方便对象的传输及储存;
它能将对象转成如XML/Bit 流;
它是Session( 进程外/SqlServer 模式),ViewState,WebService,Remoting 等的基础。
收录四:
例如学生类
public class Student
{
public int id;
public string name;
public bool sex;
public DateTime birthday;
...
}
// 序列化为byte[]
MemoryStream fs = new MemoryStream();
byte[] tmp = null;
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, student);
tmp = fs.ToArray();
将tmp 作为bianry 数据存到数据库
// 反序列化直接生成Student 类
MemoryStream fs = new MemoryStream();
Student student = null;
fs = new MemoryStream(tmp);
fs.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
student = formatter.Deserialize(fs);
操作方便不用一一赋值。
不过也有一些问题,如存到数据库以后,类Student 又添加了属性,于是就反序列化不出来了!