C#【必备技能篇】序列化与反序列化(json、xml、二进制文件)

序列化是把一个内存中的对象的信息转化成一个可以持久化保存的形式以便于保存或传输序列化的主要作用是不同平台之间进行通信常用的有序列化有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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6