C#序列化和反序列化
一、XML的序列化
using System.Xml.Serialization;
https://www.cnblogs.com/KeithWang/archive/2012/02/22/2363443.html
1.建立序列化测试对象
[XmlRootAttribute("City", Namespace = "China", IsNullable = false)] // 当该类为Xml根节点时,以此为根节点名称
public class CityXml
{
[XmlAttribute("CityId")] // 表现为Xml节点属性
public int ID { get; set; }
[XmlAttribute("CityName")] // 表现为Xml节点属性
public string Name { get; set; }
[XmlArrayAttribute("Persons")] // 表现为Xml层次结构,其所属的每个该集合节点元素名为类名
public PersonXml[] PersonXmls { get; set; }
[XmlIgnoreAttribute] // 忽略该元素的序列化
public int Sex { get; set; }
}
[XmlRootAttribute("Person")]
public class PersonXml
{
[XmlAttribute("IDCard")]
public int ID { get; set; }
[XmlElementAttribute("FullName")] // 表现为水平结构的Xml节点
public string Name { get; set; }
[XmlElementAttribute("Telephone", IsNullable = false)] // 表现为水平结构的Xml节点
public string[] Phones { get; set; }
}
2.xml序列化和反序列化
public class XmlSerialization<T>
{
public void Serialize(string path, T t)
{
XmlSerializer serializer = new XmlSerializer(t.GetType());
using (StreamWriter stream = new StreamWriter(path, false))
{
serializer.Serialize(stream, t);
}
}
public T Deserialize(string path)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StreamReader reader = new StreamReader(path))
{
return (T)serializer.Deserialize(reader);
}
}
public void Serialize(string filePath, T sourceObj, Type type, string xmlRootName)
{
if (!string.IsNullOrWhiteSpace(filePath) && sourceObj != null)
{
type = type != null ? type : sourceObj.GetType();
using (StreamWriter writer = new StreamWriter(filePath))
{
XmlSerializer xmlSerializer = string.IsNullOrWhiteSpace(xmlRootName) ?
new XmlSerializer(type) :
new XmlSerializer(type, new XmlRootAttribute(xmlRootName));
xmlSerializer.Serialize(writer, sourceObj);
}
}
}
}
3.序列化测试
public static void Xml()
{
PersonXml personXml1 = new PersonXml() { ID = 1, Name = "A" };
personXml1.Phones = new string[] { "12345", "45678" };
PersonXml personXml2 = new PersonXml() { ID = 2, Name = "B" };
personXml2.Phones = new string[] { "130458", "159789" };
PersonXml personXml3 = new PersonXml() { ID = 3, Name = "C" };
personXml3.Phones = new string[] { "139874", "134587" };
CityXml cityXml = new CityXml() { ID = 123, Name = "SZ", Sex = 0 };
cityXml.PersonXmls = new PersonXml[] { personXml1, personXml2, personXml3 };
XmlSerialization<CityXml> xmlSerialization = new XmlSerialization<CityXml>();
xmlSerialization.Serialize("CityXml.xml", cityXml);
}
4.序列化后结果对比
- 带特性的序列化
<?xml version="1.0" encoding="utf-8"?>
<City xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
CityId="123" CityName="SZ" xmlns="China">
<Persons>
<PersonXml IDCard="1">
<FullName>A</FullName>
<Telephone>12345</Telephone>
<Telephone>45678</Telephone>
</PersonXml>
<PersonXml IDCard="2">
<FullName>B</FullName>
<Telephone>130458</Telephone>
<Telephone>159789</Telephone>
</PersonXml>
<PersonXml IDCard="3">
<FullName>C</FullName>
<Telephone>139874</Telephone>
<Telephone>134587</Telephone>
</PersonXml>
</Persons>
</City>
- 不带特性的序列化
<?xml version="1.0" encoding="utf-8"?>
<CityXml xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ID>123</ID>
<Name>SZ</Name>
<PersonXmls>
<PersonXml>
<ID>1</ID>
<Name>A</Name>
<Phones>
<string>12345</string>
<string>45678</string>
</Phones>
</PersonXml>
<PersonXml>
<ID>2</ID>
<Name>B</Name>
<Phones>
<string>130458</string>
<string>159789</string>
</Phones>
</PersonXml>
<PersonXml>
<ID>3</ID>
<Name>C</Name>
<Phones>
<string>139874</string>
<string>134587</string>
</Phones>
</PersonXml>
</PersonXmls>
<Sex>0</Sex>
</CityXml>
二、Json的序列化
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
1.建立序列化测试对象
//[JsonObject(MemberSerialization.OptOut)] //默认值,类中所有公有成员会被序列化,如果不想被序列化,可以用特性JsonIgnore
//[JsonObject(MemberSerialization.OptIn)] //默认情况下,所有的成员不会被序列化,类中的成员只有标有特性JsonProperty的才会被序列化
public class CityJson
{
public int ID { get; set; }
public string Name { get; set; }
[JsonProperty(PropertyName = "Persons")] //自定义序列化的字段名称
public PersonJson[] PersonJsons { get; set; }
[JsonProperty] //序列化时默认都是处理公共成员,让私有也得到处理
private string Location { get; set; }
[JsonIgnore] // 忽略该元素的序列化
public int Sex { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] //为null值时不会序列化
public PersonJson PersonJson { get; set; }
}
public class PersonJson
{
public int ID { get; set; }
public string Name { get; set; }
public string[] Phones { get; set; }
[JsonConverter(typeof(ChinaDateTimeConverter))] //默认:"2008-04-12T12:53Z"
public DateTime Birthday { get; set; }
[JsonConverter(typeof(StringEnumConverter))] //默认:枚举对应的整型数值 加上:枚举对应的字符
public NullValueHandling NullValueHandling { get; set; }
}
2.Json序列化和反序列化
public class JsonSerialization<T>
{
public void Serialize(string path, T t)
{
using (StreamWriter sw = File.CreateText(path))
{
string json = JsonConvert.SerializeObject(t, Formatting.Indented);
sw.Write(json);
}
}
public void SerializeSettings(string path, T t)
{
using (StreamWriter sw = File.CreateText(path))
{
JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.NullValueHandling = NullValueHandling.Ignore;
string json = JsonConvert.SerializeObject(t, Formatting.Indented, jsetting);
sw.Write(json);
}
}
public T Deserialize(string path)
{
using (StreamReader sr = new StreamReader(path, Encoding.Default))
{
return JsonConvert.DeserializeObject<T>(sr.ReadToEnd());
}
}
}
3.重写部分有效的转换器
/// <summary>
/// 日期处理
/// </summary>
public class ChinaDateTimeConverter : DateTimeConverterBase
{
private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
dtConverter.WriteJson(writer, value, serializer);
}
}
/// <summary>
/// 动态决定属性是否序列化
/// </summary>
public class LimitPropsContractResolver : DefaultContractResolver
{
string[] props = null;
bool retain;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入的属性数组</param>
/// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param>
public LimitPropsContractResolver(string[] props, bool retain = true)
{
//指定要序列化属性的清单
this.props = props;
this.retain = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
//只保留清单有列出的属性
return list.Where(p =>
{
if (retain)
{
return props.Contains(p.PropertyName);
}
else
{
return !props.Contains(p.PropertyName);
}
}).ToList();
}
}
4.序列化测试
public static void Json()
{
PersonJson personJson1 = new PersonJson() { ID = 1 };
personJson1.Phones = new string[] { "12345", "45678" };
PersonJson personJson2 = new PersonJson() { ID = 2, Name = "B" };
personJson2.Phones = new string[] { "130458", "159789" };
PersonJson personJson3 = new PersonJson() { ID = 3, Name = "C" };
personJson3.Phones = new string[] { "139874", "134587" };
CityJson cityXml = new CityJson() { ID = 123, Name = "SZ", Sex = 0 };
cityXml.PersonJsons = new PersonJson[] { personJson1, personJson2, personJson3 };
JsonSerialization<CityJson> jsonSerialization = new JsonSerialization<CityJson>();
jsonSerialization.Serialize("City.json", cityXml);
}
5.序列化后的结果
{
"ID": 123,
"Name": "SZ",
"Persons": [
{
"ID": 1,
"Name": null,
"Phones": [
"12345",
"45678"
],
"Birthday": "0001-01-01 00:00:00",
"NullValueHandling": "Include"
},
{
"ID": 2,
"Name": "B",
"Phones": [
"130458",
"159789"
],
"Birthday": "0001-01-01 00:00:00",
"NullValueHandling": "Include"
},
{
"ID": 3,
"Name": "C",
"Phones": [
"139874",
"134587"
],
"Birthday": "0001-01-01 00:00:00",
"NullValueHandling": "Include"
}
],
"Location": null
}
三、bin文件的序列化
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
//序列化后不能修改空间名 (可用于深复制) 所有对象都需标记为:[Serializable]
public class BinSerialization<T>
{
public void Serialize(string path, T t)
{
using (FileStream fileStream = File.Create(path))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fileStream, t);
}
}
public T Deserialize(string path)
{
using (FileStream fileStream = File.OpenRead(path))
{
BinaryFormatter formatter = new BinaryFormatter();
object clonedObj = formatter.Deserialize(fileStream);
return (T)clonedObj;
}
}
}