序列化、反序列化物件常用的兩種方式
目錄- 序列化和反序列化物件常用的兩種方式
- 一、序列化和反序列化XML
- 1.1、序列化XML
- 1.2、反序列化XML
- 二、序列化和反序列化JSON
- 2.1、嘗試序列化資訊為JSON,并存放到文本檔案中,
- 2.2反序列化JSON檔案為物件
序列化和反序列化物件常用的兩種方式
序列化是使用指定的格式將一個或多個物件轉換為位元組序列的程序,反序列化則是相反的程序,
我們這里記錄2個常用的序列化和反序列化方法,
1、序列化為XML
2、系列化為JSON
一、序列化和反序列化XML
1.1、序列化XML
創建一個WPF程式,
新建一個類檔案命名為Person,同時我們參考以下名稱空間,創建Person的類中的屬性,
使用[XmlAtribute("fname")]屬性,會把按當前類屬性從子節點變為當前節點的屬性,檔案大小就變小了,可以嘗試一下去掉和不去掉之后產生的XML是否一樣,
using System; //DateTime
using System.Collections.Generic; //List<T>,HashSet<T>
using System.Xml.Serialization; //XmlSerializer
namespace SerializationAndDeserialization
{
public class Person
{
public Person()
{
}
public Person(decimal initialSalary)
{
Salary = initialSalary;
}
[XmlAttribute("fname")]
public string FirstName { get; set; }
[XmlAttribute("lname")]
public string LastName { get; set; }
[XmlAttribute("dob")]
public DateTime DateOfBirth { get; set; }
public HashSet<Person> Children { get; set; }
protected decimal Salary { get; set; }
}
}
在MainWindow.cs檔案中我們在建構式中實體化Person,序列化到檔案中,然后再反序列化回來,同時我們觀察使用XmlAttribute和不使用XmlAttribute有什么差別、觀察屬性定義為public型別和protected型別再序列化和反序列化程序中有什么不同,
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using static System.Console;
using static System.Environment;
using static System.IO.Path;
namespace SerializationAndDeserialization
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var people = new List<Person>()
{
new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
{ FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
};
var xs = new XmlSerializer(typeof(List<Person>));
string path = Combine(CurrentDirectory, "pepple.xaml");
using (FileStream stream = File.Create(path))
{
xs.Serialize(stream, people);
}
WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
WriteLine();
WriteLine(File.ReadAllText(path));
//系列化檔案中不包含Salary,因為是Protected型別,
//參考System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性,檔案結構就改變了,同時檔案變小了,
}
}
}

左邊是不使用再類屬性上添加 [XmlAttribute("")]的方法生成的xml檔案,右側是使用 [XmlAttribute("")]屬性,右側檔案小了很多,
1.2、反序列化XML
我們現在反序列化這個XML檔案,
我們添加代碼后完整代碼如下:
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using static System.Console;
using static System.Environment;
using static System.IO.Path;
namespace SerializationAndDeserialization
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var people = new List<Person>()
{
new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
{ FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
};
var xs = new XmlSerializer(typeof(List<Person>));
string path = Combine(CurrentDirectory, "pepple.xaml");
using (FileStream stream = File.Create(path))
{
xs.Serialize(stream, people);
}
WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
WriteLine();
WriteLine(File.ReadAllText(path));
//系列化檔案中不包含Salary,因為是Protected型別,
//參考System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性,檔案結構就改變了,同時檔案變小了,
//反序列化
using (FileStream xmlLoad = File.Open(path, FileMode.Open))
{
var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
foreach (var item in loadedPeople)
{
WriteLine($"{item.LastName} has {item.Children.Count} children.");
}
}
}
}
}
點擊運行,我們觀察VS的輸出中這三行Log,我們的反序列化就完成了,
Smith has 0 children.
Jone has 0 children.
Cox has 1 children.
二、序列化和反序列化JSON
使用JSON序列化格式的最流行的.NET庫之一是Newtonsoft.Json,又名Json.NET,
我們再專案右鍵點擊彈出選單中選擇管理NuGet包,點擊瀏覽輸入Newtonsoft.Json,選中找到的Newtonsoft.Json,點擊安裝,
2.1、嘗試序列化資訊為JSON,并存放到文本檔案中,
我們再后面添加如下代碼
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using static System.Console;
using static System.Environment;
using static System.IO.Path;
namespace SerializationAndDeserialization
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var people = new List<Person>()
{
new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
{ FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
};
var xs = new XmlSerializer(typeof(List<Person>));
string path = Combine(CurrentDirectory, "pepple.xaml");
using (FileStream stream = File.Create(path))
{
xs.Serialize(stream, people);
}
WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
WriteLine();
WriteLine(File.ReadAllText(path));
//系列化檔案中不包含Salary,因為是Protected型別,
//參考System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性,檔案結構就改變了,同時檔案變小了,
//反序列化
using (FileStream xmlLoad = File.Open(path, FileMode.Open))
{
var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
foreach (var item in loadedPeople)
{
WriteLine($"{item.LastName} has {item.Children.Count} children.");
}
}
//序列化JSON
string jsonPath = Combine(CurrentDirectory, "prople.json");
using (StreamWriter jsonStream = File.CreateText(jsonPath))
{
var jss = new Newtonsoft.Json.JsonSerializer();
jss.Serialize(jsonStream, people);
}
WriteLine();
WriteLine($"Written {new FileInfo(jsonPath).Length} bytes of JSON to :{jsonPath}");
WriteLine(File.ReadAllText(jsonPath));
}
}
}
除錯運行輸出找到Log關鍵行如下,
Written 365 bytes of JSON to :E:\C#Notes\WPF\技巧\SerializationAndDeserialization\SerializationAndDeserialization\bin\Debug\prople.json
[{"FirstName":"Alice","LastName":"Smith","DateOfBirth":"1974-03-14T00:00:00","Children":null},{"FirstName":"Bob","LastName":"Jone","DateOfBirth":"1969-11-23T00:00:00","Children":null},{"FirstName":"Charlie","LastName":"Cox","DateOfBirth":"1984-05-04T00:00:00","Children":[{"FirstName":"Sally","LastName":"Cox","DateOfBirth":"2000-07-12T00:00:00","Children":null}]}]
2.2反序列化JSON檔案為物件
反序列化的程序,我們使用File讀取檔案內容,然后使用JsonConvert.DeserializeObject 來反序列化到物件,具體代碼如下:
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using static System.Console;
using static System.Environment;
using static System.IO.Path;
using Newtonsoft.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;
namespace SerializationAndDeserialization
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var people = new List<Person>()
{
new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
{ FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
};
//序列化XML
var xs = new XmlSerializer(typeof(List<Person>));
string path = Combine(CurrentDirectory, "pepple.xaml");
using (FileStream stream = File.Create(path))
{
xs.Serialize(stream, people);
}
WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
WriteLine();
WriteLine(File.ReadAllText(path));
//系列化檔案中不包含Salary,因為是Protected型別,
//參考System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性,檔案結構就改變了,同時檔案變小了,
//反序列化XML
using (FileStream xmlLoad = File.Open(path, FileMode.Open))
{
var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
foreach (var item in loadedPeople)
{
WriteLine($"{item.LastName} has {item.Children.Count} children.");
}
}
//序列化JSON
string jsonPath = Combine(CurrentDirectory, "prople.json");
using (StreamWriter jsonStream = File.CreateText(jsonPath))
{
var jss = new Newtonsoft.Json.JsonSerializer();
jss.Serialize(jsonStream, people);
}
WriteLine();
WriteLine($"Written {new FileInfo(jsonPath).Length} bytes of JSON to :{jsonPath}");
//反序列化JSON
var jsonStr = File.ReadAllText(jsonPath);
WriteLine(File.ReadAllText(jsonPath));
var persons = JsonConvert.DeserializeObject<List<Person>>(jsonStr);
foreach (var item in persons)
{
Debug.WriteLine(item.ToString());
}
}
}
}
再Person中重寫ToString()方法用于再反序列化結束后列印輸出內容,
using System; //DateTime
using System.Collections.Generic; //List<T>,HashSet<T>
using System.Xml.Serialization; //XmlSerializer
namespace SerializationAndDeserialization
{
public class Person
{
public Person()
{
}
public Person(decimal initialSalary)
{
Salary = initialSalary;
}
[XmlAttribute("fname")]
public string FirstName { get; set; }
[XmlAttribute("lname")]
public string LastName { get; set; }
[XmlAttribute("dob")]
public DateTime DateOfBirth { get; set; }
public HashSet<Person> Children { get; set; }
protected decimal Salary { get; set; }
public override string ToString()
{
return $"FirstName:{FirstName},LastName:{LastName},DateOfBirth:{DateOfBirth}";
}
}
}
整體代碼如上,序列化xml和反序列化xml,序列化json和反序列化json都再上面,適用于NET Core之前的版本,Net Core之后的有System.Text.Json物件,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/302403.html
標籤:.NET技术
