国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - ASP.NET教程 - .Net中的序列化和反序列化詳解

.Net中的序列化和反序列化詳解

2020-01-02 13:54Learning hard ASP.NET教程

這篇文章主要介紹了.Net中的序列化和反序列化詳解的相關(guān)資料,需要的朋友可以參考下

序列化和反序列化相信大家都經(jīng)常聽(tīng)到,也都會(huì)用, 然而有些人可能不知道:.net為什么要有這個(gè)東西以及.net Frameword如何為我們實(shí)現(xiàn)這樣的機(jī)制, 在這里我也是簡(jiǎn)單談?wù)勎覍?duì)序列化和反序列化的一些理解。

一、什么序列化和反序列化
序列化通俗地講就是將一個(gè)對(duì)象轉(zhuǎn)換成一個(gè)字節(jié)流的過(guò)程,這樣就可以輕松保存在磁盤(pán)文件或數(shù)據(jù)庫(kù)中。反序列化是序列化的逆過(guò)程,就是將一個(gè)字節(jié)流轉(zhuǎn)換回原來(lái)的對(duì)象的過(guò)程。

然而為什么需要序列化和反序列化這樣的機(jī)制呢?這個(gè)問(wèn)題也就涉及到序列化和反序列化的用途了,

對(duì)于序列化的主要用途有:

1)、將應(yīng)用程序的狀態(tài)保存在一個(gè)磁盤(pán)文件或數(shù)據(jù)庫(kù)中,并在應(yīng)用程序下次運(yùn)行時(shí)恢復(fù)狀態(tài)。例如, Asp.net 中利用序列化和反2)、序列化來(lái)保存和恢復(fù)會(huì)話(huà)狀態(tài)。
3)、一組對(duì)象可以輕松復(fù)制到Windows 窗體的剪貼板中,再粘貼回同一個(gè)或者另一個(gè)應(yīng)用程序。
將對(duì)象按值從一個(gè)應(yīng)用程序域中發(fā)送到另一個(gè)程序域
并且如果把對(duì)象序列化成內(nèi)存中的字節(jié)流,就可以利用一些其他的技術(shù)來(lái)處理數(shù)據(jù),例如,對(duì)數(shù)據(jù)進(jìn)行加密和壓縮等。

 二、序列化和反序列簡(jiǎn)單使用
.Net Framework 提供二種序列化方式:

1)、二進(jìn)制序列化
2)、XML 和SOAP序列化
序列化和反序列化的簡(jiǎn)單使用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace Serializable
{
 [Serializable]
 public class Person
 {
  public string personName;
 
  [NonSerialized]
  public string personHeight;
 
  private int personAge;
  public int PersonAge
  {
   get { return personAge; }
   set { personAge = value; }
  }
 
  public void Write()
  {
   Console.WriteLine("Person Name: "+personName);
   Console.WriteLine("Person Height: " +personHeight);
   Console.WriteLine("Person Age: "+ personAge);
  }
  
 }
 class Program
 {
  static void Main(string[] args)
  {
   Person person = new Person();
   person.personName = "Jerry";
   person.personHeight = "175CM";
   person.PersonAge = 22;
   Stream stream = Serialize(person);
 
   //為了演示,都重置
   stream.Position = 0;
   person = null;
 
   person = Deserialize(stream);
   person.Write();
   Console.Read();
   
  }
  private static MemoryStream Serialize(Person person)
  {
   MemoryStream stream = new MemoryStream();
 
   // 構(gòu)造二進(jìn)制序列化格式器
   BinaryFormatter binaryFormatter = new BinaryFormatter();
   // 告訴序列化器將對(duì)象序列化到一個(gè)流中
   binaryFormatter.Serialize(stream, person);
 
   return stream;
 
  }
 
  private static Person Deserialize(Stream stream)
  {
   BinaryFormatter binaryFormatter = new BinaryFormatter();
   return (Person)binaryFormatter.Deserialize(stream);
  }
  
 }
}

主要是調(diào)用System.Runtime.Serialization.Formatters.Binary命名空間下的BinnaryFormatter類(lèi)來(lái)進(jìn)行序列化和反序列化,調(diào)用反序列化后的結(jié)果截圖:

.Net中的序列化和反序列化詳解

從中可以看出除了標(biāo)記NonSerialized的其他成員都能序列化,注意這個(gè)屬性只能應(yīng)用于一個(gè)類(lèi)型中的字段,而且會(huì)被派生類(lèi)型繼承。

SOAP 和XML 的序列化和反序列化和上面類(lèi)似,只需要改下格式化器就可以了, 這里我就不列出來(lái)了。

三、控制序列化和反序列化
  有兩種方式來(lái)實(shí)現(xiàn)控制序列化和反序列化:

通過(guò)OnSerializing, OnSerialized,OnDeserializing, OnDeserialized,NonSerialized和OptionalField等屬性
實(shí)現(xiàn)System.Runtime.Serialization.ISerializable接口
第一種方式實(shí)現(xiàn)控制序列化和反序列化代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace ControlSerialization
{
  [Serializable]
  public class Circle
  {
    private double radius; //半徑
    [NonSerialized]
    public double area; //面積
 
    public Circle(double inputradiu)
    {
      radius = inputradiu;
      area = Math.PI * radius * radius;
    }
 
    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
      area = Math.PI * radius * radius;
    }
 
    public void Write()
    {
      Console.WriteLine("Radius is: " + radius);
      Console.WriteLine("Area is: " + area);
    }
  }
  class Program
  {
    
    static void Main(string[] args)
    {
      Circle c = new Circle(10);
      MemoryStream stream =new MemoryStream();
      BinaryFormatter formatter = new BinaryFormatter();
      // 將對(duì)象序列化到內(nèi)存流中,這里可以使用System.IO.Stream抽象類(lèi)中派生的任何類(lèi)型的一個(gè)對(duì)象, 這里我使用了 MemoryStream類(lèi)型。
      formatter.Serialize(stream,c);
      stream.Position = 0;
      c = null;
      c = (Circle)formatter.Deserialize(stream);
      c.Write();
      Console.Read();
 
    }
  }
}

運(yùn)行結(jié)果為:

.Net中的序列化和反序列化詳解

注意:如果注釋掉 OnDeserialized屬性的話(huà),area字段的值就是0了,因?yàn)閍rea字段沒(méi)有被序列化到流中。 

在上面需要序列化的對(duì)象中,格式化器只會(huì)序列化對(duì)象的radius字段的值。area字段中的值不會(huì)序列化,因?yàn)樵撟侄我呀?jīng)應(yīng)用了NonSerializedAttribute屬性,然后我們用Circle c=new Circle(10)這樣代碼構(gòu)建一個(gè)Circle對(duì)象時(shí),在內(nèi)部,area會(huì)設(shè)置一個(gè)約為314.159這樣的值,這個(gè)對(duì)象序列化時(shí),只有radius的字段的值(10)寫(xiě)入流中, 但當(dāng)反序列化成一個(gè)Circle對(duì)象時(shí),它的area字段的值會(huì)初始化為0,而不是約314.159的一個(gè)值。為了解決這樣的問(wèn)題,所以自定義一個(gè)方法應(yīng)用OnDeserializedAttribute屬性。此時(shí)的執(zhí)行過(guò)程為:每次反序列化類(lèi)型的一個(gè)實(shí)例,格式化器都會(huì)檢查類(lèi)型中是否定義了 一個(gè)應(yīng)用了該attribute的方法,如果是,就調(diào)用該方法,調(diào)用該方法時(shí),所有可序列化的字段都會(huì)被正確設(shè)置。除了OnDeserializedAttribute這個(gè)定制attribute,system.Runtime.Serialization命名空間還定義了OnSerializingAttribute,OnSerializedAttribute和OnDeserializingAttribute這些定制屬性。

實(shí)現(xiàn)ISerializable接口方式控制序列化和反序列化代碼: 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Permissions;
 
namespace ControlSerilization2
{
  [Serializable]
  public class MyObject : ISerializable
  {
    public int n1;
    public intn2;
 
    [NonSerialized]
    public String str;
 
    public MyObject()
    {
    }
 
    protected MyObject(SerializationInfo info, StreamingContext context)
    {
      n1 = info.GetInt32("i");
      n2 = info.GetInt32("j");
      str = info.GetString("k");
    }
 
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)]
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
      info.AddValue("i", n1);
      info.AddValue("j", n2);
      info.AddValue("k", str);
    }
 
    public void Write()
    {
      Console.WriteLine("n1 is: " + n1);
      Console.WriteLine("n2 is: " + n2);
      Console.WriteLine("str is: " + str);
    }
  }
 
  class Program
  {
    static void Main(string[] args)
    {
      MyObject obj = new MyObject();
      obj.n1 = 2;
      obj.n2 = 3;
      obj.str = "Jeffy";
      MemoryStream stream = new MemoryStream();
      BinaryFormatter formatter = new BinaryFormatter();
      // 將對(duì)象序列化到內(nèi)存流中,這里可以使用System.IO.Stream抽象類(lèi)中派生的任何類(lèi)型的一個(gè)對(duì)象, 這里我使用了 MemoryStream類(lèi)型。
      formatter.Serialize(stream, obj);
      stream.Position = 0;
      obj = null;
      obj = (MyObject)formatter.Deserialize(stream);
      obj.Write();
      Console.Read();
    }
  }
}

結(jié)果為:

.Net中的序列化和反序列化詳解

此時(shí)的執(zhí)行過(guò)程為:當(dāng)格式化器序列化對(duì)象時(shí),會(huì)檢查每個(gè)對(duì)象,如果發(fā)現(xiàn)一個(gè)對(duì)象的類(lèi)型實(shí)現(xiàn)了ISerializable接口,格式化器會(huì)忽視所有定制屬性,改為構(gòu)造一個(gè)新的System.Runtime.Serialization.SerializationInfo對(duì)象,這個(gè)對(duì)象包含了要實(shí)際為對(duì)象序列化的值的集合。構(gòu)造好并初始化好SerializationInfo對(duì)象后,格式化器調(diào)用類(lèi)型的GetObjectData方法,并向它傳遞對(duì)SerializationInfo對(duì)象的引用,GetObjectData方法負(fù)責(zé)決定需要哪些信息來(lái)序列化對(duì)象,并將這些信息添加到SerializationInfo對(duì)象中,通過(guò)調(diào)用AddValue方法來(lái)添加需要的每個(gè)數(shù)據(jù),添加好所有必要的序列化信息后,會(huì)返回至格式化器,然后格式化器獲取已經(jīng)添加到SerializationInfo對(duì)象中的所有值,并將它們都序列化到流中,當(dāng)反序列化時(shí),格式化器從流中提取一個(gè)對(duì)象時(shí),會(huì)為新對(duì)象分配內(nèi)存,最初,這個(gè)對(duì)象的所有字段都設(shè)為0或null,然后,格式化器檢查類(lèi)型是否實(shí)現(xiàn)了ISerializable接口,如果存在這個(gè)接口, 格式化器就嘗試調(diào)用一個(gè)特殊構(gòu)造器,它的參數(shù)和GetObjectData方法的完全一致。

四、格式化器如何序列化和反序列化
從上面的分析中可以看出,進(jìn)行序列化和反序列化主要是格式化器在工作的,然而下面就是要講講格式化器是如何序列化一個(gè)應(yīng)用了 SerializableAttribute 屬性的對(duì)象。

1、格式化器調(diào)用FormatterServices的GetSerializableMembers方法:public static MemberInfo[] GetSerializableMembers(Type type,StreamingContext context);這個(gè)方法利用發(fā)射獲取類(lèi)型的public和private實(shí)現(xiàn)字段(標(biāo)記了NonSerializedAttributee屬性的字段除外)。方法返回由MemberInfo對(duì)象構(gòu)成的一個(gè)數(shù)組,其中每個(gè)元素對(duì)應(yīng)于一個(gè)可序列化的實(shí)例字段。
2、對(duì)象被序列化,System.Reflection.MemberInfo對(duì)象數(shù)組傳給FormatterServices的靜態(tài)方法GetObjectData: public static object[] GetObjectData(Object obj,MemberInfo[] members);  這個(gè)方法返回一個(gè)Object數(shù)組,其中每個(gè)元素都標(biāo)識(shí)了被序列化的那個(gè)對(duì)象中的一個(gè)字段的值。
3、格式化器將程序集標(biāo)識(shí)和類(lèi)型的完整名稱(chēng)寫(xiě)入流中。
4、格式化器然后遍歷兩個(gè)數(shù)組中的元素,將每個(gè)成員的名稱(chēng)和值寫(xiě)入流中。
接下來(lái)是解釋格式化器如何自動(dòng)反序列化一個(gè)應(yīng)用了 SerializableAttribute屬性的對(duì)象。

1、格式化器從流中讀取程序集標(biāo)識(shí)和完整類(lèi)型名稱(chēng)。
2、格式化器調(diào)用FormatterServices的靜態(tài)方法GetUninitializedObject: public static Object GetUninitializedObject(Type ttype);這個(gè)方法為一個(gè)新對(duì)象分配內(nèi)存,但不為對(duì)象調(diào)用構(gòu)造器。然而,對(duì)象的所有字段都被初始化為0或null.
3格式化器現(xiàn)在構(gòu)造并初始化一個(gè)MemberInfo數(shù)組,調(diào)用FormatterServices的GetSerializableMembers方法,這個(gè)方法返回序列化好、現(xiàn)在需要反序列化的一組字段。
4、格式化器根據(jù)流中包含的數(shù)據(jù)創(chuàng)建并初始化一個(gè)Object數(shù)組。
5、將對(duì)新分配的對(duì)象、MemberInfo數(shù)組以及并行Object數(shù)組的引用傳給FormatterServices的靜態(tài)方法PopulateObjectMembers:
          public static Object PopulateObjectMembers(Object obj,MemberInfo[] members,Object[] data);這個(gè)方法遍歷數(shù)組,將每個(gè)字段初始化成對(duì)應(yīng)的值。

注:格式化如何序列化和反序列對(duì)象部分摘自CLR via C#(第三版),寫(xiě)在這里可以讓初學(xué)者進(jìn)一步理解格式化器在序列化和反序列化過(guò)程中所做的工作。

 寫(xiě)到這里這篇關(guān)于序列化和反序列的文章終于結(jié)束了, 希望對(duì)朋友有幫助。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品一区二区三区免费视频 | 亚洲午夜精品久久久久久高潮 | 国产黄色电影 | 精品国偷自产国产一区 | 精品欧美| 99久久精品国产一区二区三区 | 亚洲黄色成人 | 久一久久| 女人性做爰免费网站 | h片在线| 欧美精品国产精品 | 国产精品女教师av久久 | 日韩色av| 中文字幕高清在线播放 | 97精品超碰一区二区三区 | 久久伊人久久 | 综合二区 | 中文字幕一区在线观看视频 | 五月婷婷导航 | 91免费在线 | 狠狠操av| 亚洲激情精品 | 久久精品国产视频 | 国产精品成人国产乱一区 | 在线成人亚洲 | 国产精品一区二区三区免费 | 日本成人一区 | 国产激情偷乱视频一区二区三区 | 久久中文在线观看 | 97久久久| 亚洲一区二区av | 国产免费自拍av | 日韩成人在线影院 | 亚洲成人中文字幕 | 色综合久久88色综合天天 | 中文精品在线观看 | 免费一区二区三区 | 天天看天天操 | 免费一区 | 亚洲国产一区二区三区日本久久久 | 成人激情免费 |