二进制序列化器、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"}
相关文章
|
2月前
|
XML JSON 前端开发
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(简单支持发起人与审批人的流程)
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(简单支持发起人与审批人的流程)
166 2
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(简单支持发起人与审批人的流程)
|
2月前
|
XML JSON 前端开发
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(支持并行网关)
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(支持并行网关)
148 3
|
7天前
|
JSON Dart 安全
Flutter Dart Macro 宏简化 JSON 序列化
今天我们将会体验 dart 语言新特性 macro 宏,来实现对 json 的序列化,用到的包是官方实验室写的 json 包。 本文将会一步步的带你实现这个功能,那我们开始吧。
Flutter Dart Macro 宏简化 JSON 序列化
|
26天前
|
XML JSON 缓存
优化Java中XML和JSON序列化
优化Java中XML和JSON序列化
|
2月前
|
XML JSON 前端开发
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
49 3
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
|
1月前
|
XML JSON 开发框架
一篇文章讲明白JSON格式转换成XML格式
一篇文章讲明白JSON格式转换成XML格式
12 0
|
1月前
|
XML JSON 开发框架
一篇文章讲明白JSON格式转换成XML格式
一篇文章讲明白JSON格式转换成XML格式
13 0
|
2月前
|
XML JSON 前端开发
初学者指南:JSON 和 XML 的区别
当我们讨论数据交换格式时,JSON(JavaScript对象表示法)和 XML(可扩展标记语言)无疑是最受欢迎的两种选择。这两者各有优点和缺点,根据具体的应用场景,选择合适的格式可以显著提高开发效率和系统性能。
|
2月前
|
XML 存储 JSON
c#XML、JSON的序列化和反序列化,看完你就懂了
c#XML、JSON的序列化和反序列化,看完你就懂了
53 0
|
1月前
|
XML Java 数据格式
java创建xml文件内容
java创建xml文件内容
19 0