收錄一:
我的理解:
比如用一個(gè)類描述一張合同,而這個(gè)類實(shí)例化后其中的字段保存著合同的信息,如果現(xiàn)在要把這個(gè)類的實(shí)例發(fā)送到另一臺(tái)機(jī)器、另一個(gè)窗體或是想保存這個(gè)類以便以后再取出來(lái)用(持久化對(duì)象),可以對(duì)這個(gè)類進(jìn)行序列化(序列化實(shí)際上是一個(gè)信息流),傳送或保存,用的時(shí)候再反序列化重新生成這個(gè)對(duì)象
為什么您想要使用序列化?有兩個(gè)最重要的原因促使對(duì)序列化的使用:一個(gè)原因是將對(duì)象的狀態(tài)保持在存儲(chǔ)媒體中,以便可以在以后重新創(chuàng)建精確的副本;另一個(gè)原因是通過值將對(duì)象從一個(gè)應(yīng)用程序域發(fā)送到另一個(gè)應(yīng)用程序域中。例如,序列化可用于在 ASP.NET 中保存會(huì)話狀態(tài)并將對(duì)象復(fù)制到 Windows 窗體的剪貼板中。遠(yuǎn)程處理還可以使用序列化通過值將對(duì)象從一個(gè)應(yīng)用程序域傳遞到另一個(gè)應(yīng)用程序域中。
序列化的是對(duì)象的狀態(tài)
也就是對(duì)象數(shù)據(jù)成員的值和方法是沒有關(guān)系的
跨應(yīng)用程序域通信時(shí),要用到序列化
以及用WEB服務(wù)時(shí)
一:BinaryFormatter序列化
序列化簡(jiǎn)單點(diǎn)來(lái)理解就是把內(nèi)存的東西寫到硬盤中,當(dāng)然也可以寫到內(nèi)存中(這個(gè)內(nèi)容我會(huì)在后面寫一個(gè)例子).而反序列化就是從硬盤中把信息讀到內(nèi)存中.就這么簡(jiǎn)單,呵呵,現(xiàn)在來(lái)看下面的例子吧!
在這篇文章中我將使用BinaryFormatter序列化類Book作為例子,希望大家能從例子中深刻體會(huì)什么是序列化.
定義類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.(如果不加這個(gè)屬性,將拋出SerializationException異常).
通過這個(gè)屬性將Book標(biāo)志為可以序列化的.當(dāng)然也有另一種方式使類Book可以序列化,那就是實(shí)行ISerializable接口了.在這里大家要注意了:Serializable屬性是不能被繼承的咯!!!
如果你不想序列化某個(gè)變量,該怎么處理呢?很簡(jiǎn)單,在其前面加上屬性[NonSerialized] .比如我不想序列化
string author;
那我只需要
[NonSerialized]
string author;
好了,現(xiàn)在就告訴大家怎么實(shí)現(xiàn)序列化:
我們使用namespace:
using System;
using System.IO;
using System.RunTime.Serialization.Formatters.Binary;
首先創(chuàng)建Book實(shí)例,like this:
Book book = new Book("Day and Night", Numbertype="1" tcsc="0">30.0f, "Bruce");
接著當(dāng)然要?jiǎng)?chuàng)建一個(gè)文件了,這個(gè)文件就是用來(lái)存放我們要序列化的信息了.
FileStream fs = new FileStream(@"C:\book.dat", FileMode.Create);
序列化的實(shí)現(xiàn)也很簡(jiǎn)單,like this:
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, book);
很簡(jiǎn)單吧!現(xiàn)在我列出整個(gè)原代碼,包括反序列化.
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
}
}
有不對(duì)的地方,請(qǐng)大家多多糾正.....
注意一定不要忘了: using System.Runtime.Serialization.Formatters.Binary;
命名空間。
收錄二:
原先一直用BinaryFormatter來(lái)序列化挺好,可是最近發(fā)現(xiàn)在WinCE下是沒有辦法進(jìn)行BinaryFormatter操作,很不爽,只能改成了BinaryWriter和BinaryReader來(lái)讀寫,突然想到能不能用XML來(lái)序列化?于是在網(wǎng)上查了些資料便寫了些實(shí)踐性代碼,做些記錄,避免以后忘記。
序列化對(duì)象
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);
}
反序列化對(duì)象
XmlSerializer ser = new XmlSerializer(typeof(Student));
Student stu = ser.Deserialize(File.OpenRead("C:\\x.xml")) as Student;
對(duì)象數(shù)組序列化
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);
}
對(duì)象數(shù)組反序列
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);
}
這里還要講一點(diǎn),在XmlSerializer中,不支持Dirctionary<>類型的對(duì)象,所以在序列化這種最常見類型的時(shí)候,只能按照它的格式先創(chuàng)建一個(gè)可以別序列化的類型,這里我定義了一個(gè)結(jié)構(gòu)體,當(dāng)然你也可以定義成其他的類。將Dictionary<>中的數(shù)據(jù)依次放進(jìn)結(jié)構(gòu)體以后就可以放入流中了。
[XmlAttribute("Name")]意思是將這個(gè)字段作為xml的屬性,屬性名跟在“”中
[XmlElement("Value")]意思是將這個(gè)字段做為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);
}
其實(shí)我并不喜歡這個(gè)名稱,感覺有點(diǎn)生化危機(jī)的feel,但是也就是這樣了,沒有太炫的地方,Deserialize反序列化。真希望.Net能集成Dirctionary<>對(duì)象,那我們這些懶人就方便了。
在需要序列化的隊(duì)伍中,數(shù)組是很常見的類型,其次就是圖片了
序列化圖片
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();
}
一樣的,采用結(jié)構(gòu)體來(lái)保存圖片,這里我還加了個(gè)圖片的名字,到時(shí)候查找起來(lái)也方便一些
圖片反序列化
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來(lái)做緩存,這樣會(huì)比較快一點(diǎn),實(shí)際上我并沒有怎么感覺。
圖片數(shù)組序列化
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();
}
圖片數(shù)組反序列化
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));
}
這里還對(duì)數(shù)組結(jié)構(gòu)進(jìn)行了Linq查詢,這樣就可以很方便的查詢圖片了。
收錄三:
序列化方便對(duì)象的傳輸及儲(chǔ)存;
它能將對(duì)象轉(zhuǎn)成如XML/Bit流;
它是Session(進(jìn)程外/SqlServer模式),ViewState,WebService,Remoting等的基礎(chǔ)。
收錄四:
例如學(xué)生類
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數(shù)據(jù)存到數(shù)據(jù)庫(kù)
// 反序列化直接生成Student類
MemoryStream fs = new MemoryStream();
Student student = null;
fs = new MemoryStream(tmp);
fs.Position = 0;
BinaryFormatter formatter = new BinaryFormatter();
student = formatter.Deserialize(fs);
操作方便不用一一賦值。
不過也有一些問題,如存到數(shù)據(jù)庫(kù)以后,類Student又添加了屬性,于是就反序列化不出來(lái)了!