二进制序列化器、XML序列化器、Json序列化器

简介: 序列化是将对象的状态信息转换未可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区读取或反序列化对象的状态,重新创建对象。

序列化是将对象的状态信息转换未可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区读取或反序列化对象的状态,重新创建对象。

序列化之前:对象

序列化之后:把对象转换成另一种形式存储

1、二进制序列化器

BinaryFormatter

保存成二进制数据流。

示例:

序列化:
public class Student
    {
        public Student(int id, string name, int age, string grade)
        {
            this.ID = id;
            this.Name = name;
            this.Age = age;
            this.Grade = grade;
        }
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Grade { get; set; }
    }
`
`
class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            for (int i = 1; i < 10; i++)
            {
                Student student = new Student(i, "学生" + i, 18 + i, "年级二");
                students.Add(student);
            }

            FileStream fileStream = new FileStream(@"E:\dotnet\SerilizeAndDeserialize\SerilizeAndDeserialize\data\student.dat", FileMode.OpenOrCreate);
            BinaryFormatter bFormat = new BinaryFormatter();
            bFormat.Serialize(fileStream, students);
            fileStream.Close();
            Console.WriteLine("序列化成功");
        }
    }
`

运行代码,此时会遇到如下图报错;

Student没有标记序列化。

解决方法
   [Serializable]
   //如果要想保存某个class中的字段,必须在class前面加个这样Attribute
    public class Student
    {
        public Student(int id, string name, int age, string grade)
        {
            this.ID = id;
            this.Name = name;
            this.Age = age;
            this.Grade = grade;
        }
        public int ID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Grade { get; set; }
    }

之后可以看到成功序列化后,保存至student.dat文件中。

反序列化:
FileStream stream = new FileStream(@"E:\dotnet\SerilizeAndDeserialize\SerilizeAndDeserialize\data\student.dat", FileMode.Open);
            BinaryFormatter bdFormat = new BinaryFormatter();
            List<Student> students1 = (List<Student>)bFormat.Deserialize(stream);
            stream.Close();
Console.WriteLine("反序列化成功");
进一步地:

从 .NET 5.开始,以下 API 标记为已过时

详见:

SYSLIB0011:BinaryFormatter 序列化已过时

解决方法

请考虑使用 JsonSerializerXmlSerializer,而不是 BinaryFormatter

2、XML序列化器

XmlSerializer

保存成XML文件,但没有其他额外信息。另外需要注意的是,XmlSerializer只能保存public类型的字段,而其他两种类型能保存所有类型的字段。

序列化:

            Circle circle = new Circle
            {
                Radius = 10.1,
                BgColor = "Black"
            };
            XmlDocument xd = new XmlDocument();
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(circle.GetType());
                xz.Serialize(sw, circle);
                Console.WriteLine(sw.ToString());
                xd.LoadXml(sw.ToString());
                xd.Save(@"E:\C#\SerilizeAndDeserialize\SerilizeAndDeserialize\data\circle.xml");
            }

反序列化:

Circle circle2 = new Circle();
            using (XmlReader reader = XmlReader.Create(@"E:\C#\SerilizeAndDeserialize\SerilizeAndDeserialize\data\circle.xml"))
            {
                XmlSerializer xz = new XmlSerializer(circle2.GetType());
                circle2 = (Circle)xz.Deserialize(reader);
                Console.WriteLine(reader.ToString());
            }

三、JSON序列化器

Json序列化有很多种方法,这里我们介绍.Net 标准库 System.Text.JsonSystem.Runtime.Serialization.Json 和 Newtonsoft 库Newtonsoft.Json;

System.Text.Json
            Circle circle = new Circle
            {
                Radius = 10.1,
                BgColor = "Black"
            };
            string json = JsonSerializer.Serialize(circle); //序列化
            Circle circle2 = JsonSerializer.Deserialize<Circle>(json); //反序列化
Newtonsoft.Json
string json = JsonConvert.SerializeObject(circle); //序列化
Circle circle2 = JsonConvert.DeserializeObject<Circle>(json); //反序列化
System.Runtime.Serialization.Json
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Circle));
            using (MemoryStream memoryStream = new MemoryStream())
            {
                dataContractJsonSerializer.WriteObject(memoryStream, circle);
            }
DataContractJsonSerializer dataContractJsonSerializer1 = new DataContractJsonSerializer(typeof(Circle));
            MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonText));
            Circle result = (Circle)((object)dataContractJsonSerializer1.ReadObject(memoryStream));
Newtonsoft.Json.Linq中的JObject类型

以上例子都是使用强类型进行序列化和反序列操作,但有时也会用到不指定类型而直接操作Json格式数据的情况,此时就需要用位于命名空间ewtonsoft.Json.Linq中的JObject类型的对象:

string jsonStr = @"{""MyNum"": 10,""MyStr"": ""Hello World""}";
JObject jObject = JObject.Parse(jsonStr);
Console.WriteLine(jObject.ToString(Formatting.None)); //{"MyNum":10,"MyStr":"Hello World"}
//打印一条属性的值
Console.WriteLine(jObject["MyStr"].Value<string>()); //Hello World
//添加一条属性
jObject.Add("MyStr2", "HaHa");
//打印当前Json字符串
Console.WriteLine(jObject.ToString(Formatting.None)); //{"MyNum":10,"MyStr":"Hello World","MyStr2":"HaHa"}

四、自定义某个字段/属性的序列化/反序列化规则

当接收到的Json格式字符串与本地已有类型不统一时,需要进行自定义的反序列化过程,反之亦然,例如Json字符串中以字符串"TRUE"表示布尔类型true(不自定义,这个过程依然走的通,只是以此举例),以字符串"FALSE"表示布尔类型false时,需要自定义如下:

/// <summary>
/// 自定义布尔类型数据转换规则
/// </summary>
public class MyBoolConverter : JsonConverter{
  private const string TrueStr = "TRUE";
  private const string FalseStr = "FALSE";
  public override bool CanConvert(Type objectType) => true;

  //反序列化  
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)  {
    if (reader.ValueType == typeof(string))
    {
      if ((string)reader.Value == TrueStr)
      {
        return true;
      }
      else      {
        return false;
      }
    }
    return false;
  }

  //序列化  
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)  {
    if (value.GetType() == typeof(bool))
    {
      bool result = (bool)value;
      if (result)
      {
        writer.WriteValue(TrueStr);
      }
      else      {
        writer.WriteValue(FalseStr);
      }
    }
  }
}

然后,在需要操作的类型定义中的字段/属性中加入该特性:

private class MyClass{
  [JsonConverter(typeof(MyBoolConverter))]
  public bool MyBool;
}

此时

string jsonStr = @"{""MyBool"": ""TRUE""}";
MyClass1 myClass = JsonConvert.DeserializeObject<MyClass1>(jsonStr);
Console.WriteLine(myClass.MyBool); //True
Console.WriteLine(JsonConvert.SerializeObject(myClass)); //{"MyBool":"TRUE"}
相关文章
|
17天前
|
JSON JavaScript 前端开发
Go语言中json序列化的一个小坑,建议多留意一下
在Go语言开发中,JSON因其简洁和广泛的兼容性而常用于数据交换,但其在处理数字类型时存在精度问题。本文探讨了JSON序列化的一些局限性,并介绍了两种替代方案:Go特有的gob二进制协议,以及msgpack,两者都能有效解决类型保持和性能优化的问题。
44 7
|
21天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
31 4
|
25天前
|
JSON JavaScript Java
对比JSON和Hessian2的序列化格式
通过以上对比分析,希望能够帮助开发者在不同场景下选择最适合的序列化格式,提高系统的整体性能和可维护性。
34 3
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
JSON JavaScript 前端开发
|
2月前
|
XML JSON 数据可视化
数据集学习笔记(二): 转换不同类型的数据集用于模型训练(XML、VOC、YOLO、COCO、JSON、PNG)
本文详细介绍了不同数据集格式之间的转换方法,包括YOLO、VOC、COCO、JSON、TXT和PNG等格式,以及如何可视化验证数据集。
193 1
数据集学习笔记(二): 转换不同类型的数据集用于模型训练(XML、VOC、YOLO、COCO、JSON、PNG)
|
2月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
450 0
|
3月前
|
JSON 数据格式
序列化 json和pickle
序列化 json和pickle
|
2月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
67 1
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)

热门文章

最新文章