文章目录
- 一、序列化为json
- 1、序列化与反序列化【基本使用】
- 实例代码:
- 2、封装成泛型方法【可以公用】
- 实例代码:
- 二、序列化为xml
- 1、序列化与反序列化【基本使用】
- 实例代码:
- 2、封装成泛型方法【可以公用】
- 实例代码:
- 三、序列化为二进制文件
- 1、序列化与反序列化【基本使用】
- 实例代码:
- 2、封装成泛型方法【可以公用】
- 实例代码:
- 3、补充【项目中实际代码,供参考】
- 参考:
序列化是把一个内存中的对象的信息转化成一个可以持久化保存的形式,以便于保存或传输,序列化的主要作用是不同平台之间进行通信,常用的有序列化有json、xml、二进制文件等,下面就逐个讲下这三种序列化的方法。
一、序列化为json
1、序列化与反序列化【基本使用】
C#中用于对象和json相互转换的原生类有两个:DataContractJsonSerializer和JavaScriptSerializer,其中JavaScriptSerializer主要用于web的浏览器和服务器之间的通信。
这里主要讲DataContractJsonSerializer
的使用,要使用DataContractJsonSerializer,先要在项目中引用System.Runtime.Serialization
。首先准备一个测试的类Book:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;//添加的引用
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
[DataContract]
public class Book
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public float Price { get; set; }
}
}
[DataContract]
指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。
[DataMember]
当应用于类型的成员时,指定该成员是数据协定的一部分并可由 System.Runtime.Serialization.DataContractSerializer进行序列化。
序列化:
然后先创建一个Book对象,实例化一个DataContractJsonSerializer实例,最后用该实例的WriteObject()方法将对象写到流中。
反序列化:
将一个json格式的字符串反序列化为对象是用DataContractJsonSerializer实例的ReadObject()方法。
实例代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;//添加的引用
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
public class Program
{
static void Main(string[] args)
{
//序列化json
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(Book));
using (MemoryStream stream = new MemoryStream())
{
formatter.WriteObject(stream, book);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(result);
}
Console.WriteLine();
//反序列化json
string oriStr = "{\"ID\":102,\"Name\":\"C# wpf程序设计\",\"Price\":100}";
DataContractJsonSerializer formatter1 = new DataContractJsonSerializer(typeof(Book));
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(oriStr)))
{
Book outBook = formatter1.ReadObject(stream) as Book;
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
}
Console.ReadLine();
}
}
}
2、封装成泛型方法【可以公用】
实例代码:
Program.cs【核心代码】
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
//【01】Book类
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
//序列化json
string result = Serializer.ObjectToJson<Book>(book);
Console.WriteLine(result);
Console.WriteLine();
//反序列化json
string oriStr = "{\"ID\":101,\"Name\":\"C#程序设计\",\"Price\":79.5}";
Book outBook = Serializer.JsonToObject<Book>(oriStr);
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
Console.WriteLine();
Console.WriteLine("——————————————————————");
//【02】Student类
Student student = new Student() { ID = 5, Name = "Star", Age = 30 };
//序列化json
string result1 = Serializer.ObjectToJson<Student>(student);
Console.WriteLine(result1);
Console.WriteLine();
//反序列化json
string oriStr1 = "{\"ID\":5,\"Name\":\"Star\",\"Age\":29}";
Student outStudent = Serializer.JsonToObject<Student>(oriStr1);
Console.WriteLine(outStudent.ID);
Console.WriteLine(outStudent.Name);
Console.WriteLine(outStudent.Age);
Console.Read();
}
}
public class Serializer
{
/// 将对象序列化为json文件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <param name="path">存放路径</param>
public static void ObjectToJson<T>(T t, string path) where T : class
{
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T));
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
formatter.WriteObject(stream, t);
}
}
/// <summary>
/// 将对象序列化为json字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <returns>json字符串</returns>
public static string ObjectToJson<T>(T t) where T : class
{
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
formatter.WriteObject(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
}
/// <summary>
/// json字符串转成对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="json">json格式字符串</param>
/// <returns>对象</returns>
public static T JsonToObject<T>(string json) where T : class
{
DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)))
{
T result = formatter.ReadObject(stream) as T;
return result;
}
}
}
}
Book.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
[DataContract]
public class Book
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public float Price { get; set; }
}
}
Student.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
[DataContract]
public class Student
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
}
}
二、序列化为xml
C#中将对象序列化和反序列化为xml的类是XmlSerializer
,要引用System.Xml.Serialization
1、序列化与反序列化【基本使用】
序列化:
先创建一个XmlSerializer对象实例,然后用实例的Serialize的方法将对象写入到文件流中。
当然也可以将对象转换成对象流,然后转换成xml格式的字符串。
反序列化:
将xml文件反序列化的方法是用XmlSerializer实例的Deserialize()方法
实例代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
//[1]序列化
XmlSerializer formatter = new XmlSerializer(typeof(Book));
//保存为文件
using (FileStream stream = new FileStream(@".\book.xml", FileMode.OpenOrCreate))
{
formatter.Serialize(stream, book);
}
//转换为xml格式的字符串
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, book);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());//转换成xml字符串
Console.WriteLine(result);
}
Console.WriteLine("——————————————————————");
//[2]反序列化
XmlSerializer formatter1 = new XmlSerializer(typeof(Book));
using (FileStream stream = new FileStream(@".\book.xml", FileMode.OpenOrCreate))
{
XmlReader xmlReader = new XmlTextReader(stream);
Book outBook = formatter.Deserialize(xmlReader) as Book;//反序列化
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
}
Console.Read();
}
}
}
2、封装成泛型方法【可以公用】
实例代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.6f };
//序列化xml
Serializer.ObjectToXml(book, @".\book.xml");
//反序列化xml
Book outBook = Serializer.XmlToObject(book, @".\book.xml");
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
Console.Read();
}
}
public class Serializer
{
/// <summary>
/// 将对象序列化为xml文件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
/// <param name="path">xml存放路径</param>
public static void ObjectToXml<T>(T t, string path) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
formatter.Serialize(stream, t);
}
}
/// <summary>
/// 将对象序列化为xml字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
public static string ObjectToXml<T>(T t) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
}
/// <summary>
/// 将xml文件反序列化为对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
/// <param name="path">xml路径</param>
/// <returns>对象</returns>
public static T XmlToObject<T>(T t, string path) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
XmlReader xmlReader = new XmlTextReader(stream);
T result = formatter.Deserialize(xmlReader) as T;
return result;
}
}
}
}
三、序列化为二进制文件
1、序列化与反序列化【基本使用】
C#中将对象序列化为二进制文件的类是BinaryFormatter
,要引用System.Runtime.Serialization.Formatters.Binary
序列化:
先创建一个BinaryFormatter对象实例,然后用实例的Serialize的方法将对象写入到文件流中
反序列化:
可以通过BinaryFormatter类型实例的Deserialize()方法把二进制文本反序列化为对象
实例代码:
Program.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp5
{
internal class Program
{
static void Main(string[] args)
{
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
//序列化文件
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream(@".\book.txt", FileMode.OpenOrCreate))
{
formatter.Serialize(stream, book);
}
//反序列化文件
BinaryFormatter formatter1 = new BinaryFormatter();
using (FileStream stream = new FileStream(@".\book.txt", FileMode.OpenOrCreate))
{
Book outBook = formatter1.Deserialize(stream) as Book;
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
}
Console.Read();
}
}
}
Book.cs:【注意下边是 : [Serializable]】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp5
{
[Serializable]
public class Book
{
public int ID { get; set; }
public string Name { get; set; }
public float Price { get; set; }
}
}
程序执行完成后产生bool.txt文件,如图:
2、封装成泛型方法【可以公用】
实例代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };
//序列化文件
Serializer.ObjectToFile(book, @".\book.txt");
//序列化为字符串
string result = Serializer.ObjectToString<Book>(book);
Console.WriteLine(result);//这里显示为乱码
Console.WriteLine("——————————————————");
//文件反序列化为类型
Book outBook = Serializer.FileToObject<Book>(@".\book.txt") as Book;
Console.WriteLine(outBook.ID);
Console.WriteLine(outBook.Name);
Console.WriteLine(outBook.Price);
Console.WriteLine("——————————————————");
//字符串反序列化为类型【测试失败,报异常:System.Runtime.Serialization.SerializationException:“没有对象“201326592”的映射。”】
//Book outBook1 = Serializer.StringToObject<Book>(result);
//Console.WriteLine(outBook1.ID);
//Console.WriteLine(outBook1.Name);
//Console.WriteLine(outBook1.Price);
Console.Read();
}
}
public class Serializer
{
/// <summary>
/// 将对象序列化为字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <returns>字符串</returns>
public static string ObjectToString<T>(T t)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
}
/// <summary>
/// 将对象序列化为文件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <param name="path">存放路径</param>
public static void ObjectToFile<T>(T t, string path)
{
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
formatter.Serialize(stream, t);
stream.Flush();
}
}
/// <summary>
/// 将字符串反序列为类型
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="s">字符串</param>
/// <returns>对象</returns>
public static T StringToObject<T>(string s) where T : class
{
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(s);
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream(buffer))
{
T result = formatter.Deserialize(stream) as T;//报异常:System.Runtime.Serialization.SerializationException:“没有对象“201326592”的映射。”
return result;
}
}
/// <summary>
/// 将文件反序列化为对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="path">路径</param>
/// <returns>对象</returns>
public static T FileToObject<T>(string path) where T : class
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
T result = formatter.Deserialize(stream) as T;
return result;
}
}
}
}
上边注释部分若释放,会报如下异常:【???】
3、补充【项目中实际代码,供参考】
序列化:保存为二进制文件
反序列化:打开一个二进制文件,并转换为类实例对象
参考:
https://www.cnblogs.com/maitian-lf/p/3670570.html