【C#进阶七】C#中的序列化与反序列化上(二进制序列化、XML序列化及JSON序列化)

在这里插入图片描述

1. C# 序列化介绍

序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。 它的主要用途是保存对象的状态,以便能够在需要时重新创建对象。 反向过程称为“反序列化”。

主要用途:

  • 使用 Web 服务将对象发送到远程应用程序
  • 将对象从一个域传递到另一个域
  • 将对象通过防火墙传递为 JSON 或 XML 字符串
  • 跨应用程序维护安全或用户特定的信息

图:序列化

序列化方式:

  • 二进制序列化保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。 例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。 您可以将对象序列化到流、磁盘、内存和网络等。 远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。
  • XML 和 SOAP 序列化只序列化公共属性和字段,并且不保持类型保真。 当您希望提供或使用数据而不限制使用该数据的应用程序时,这一点非常有用。 由于 XML 是开放式的标准,因此它对于通过 Web 共享数据来说是一个理想选择。 SOAP 同样是开放式的标准,这使它也成为一个理想选择。
  • JSON 序列化只序列化公共属性,并且不保持类型保真。 JSON 是开放式的标准,对于通过 Web 共享数据来说是一个理想选择。

2.XML序列化与反序列化

2.1 XML序列化代码示例

使用 XmlSerializer类从某个类将对象写入 XML 文件。

 public class XMLWrite
 {
     static void Main(string[] args)
     {
         WriteXML();
     }
     //新建一个book类     
     public class Book
     {
         public String title { get; set; } = String.Empty;
         public String content { get; set; } = String.Empty;
     }
     public static void WriteXML()
     {
         Book overview = new Book();
         overview.title = "Serialization Overview";
         overview.content = "智能建造小硕";
         //新建一个Book类型的XML类
         System.Xml.Serialization.XmlSerializer writer =
             new System.Xml.Serialization.XmlSerializer(typeof(Book));
         //获取系统指定文件夹的路径,
         var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializationOverview.xml";
         System.IO.FileStream file = System.IO.File.Create(path);
         writer.Serialize(file, overview);
         file.Close();
         Console.WriteLine("序列化成功");
     }
 }

运行结果

保存的XML文件,在C盘系统默认文件所在文件夹下:

image-20220830102020634

2.2 XML反序列化代码示例

使用 XmlSerializer类从某个类将对象写入 XML 文件。

 public class XMLWrite
 {
 static void Main(string[] args)
 {
 ReadXML();
 }
 //新建一个book类     
 public class Book
 {
 public String title { get; set; } = String.Empty;
 public String content { get; set; } = String.Empty;
 }  
 public static void ReadXML()
 {
 //读取XML序列化的文件进行反序列化
 System.Xml.Serialization.XmlSerializer reader =
 new System.Xml.Serialization.XmlSerializer(typeof(Book));
 var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "//SerializationOverview.xml";
 System.IO.StreamReader file = new System.IO.StreamReader(path);
 Book overview = (Book)reader.Deserialize(file);
 file.Close();
 Console.WriteLine(overview.title);
 Console.WriteLine(overview.content);
 }
 }

运行结果

Serialization Overview
智能建造小硕

3. JSON序列化与反序列化

3.1 Json序列化

代码示例一:

public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }
public class Program
{
    public static void Main()
    {
        var weatherForecast = new WeatherForecast
        {
            //求位于当前年月日内的时间
            Date = DateTime.Parse("2022-08-30"),
            TemperatureCelsius = 25,
            Summary = "Hot"
        };
        string fileName = "G:\\Desktop\\archive1" + "\\WeatherForecast.json";
        string jsonString = JsonSerializer.Serialize(weatherForecast);
        File.WriteAllText(fileName, jsonString);
        Console.WriteLine(File.ReadAllText(fileName));
    }
}

小知识:

引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。
例如:string str=null; 是正确的,int i=null; 编译器就会报错。
为了使值类型也可为空,就可以使用可空类型,即用可空类型修饰符"?“来表示,表现形式为"T?”

例如: DateTime? date = null; // 等价于 Nullable<DateTime> date = null;

在赋值时为了避免抛出异常,需要做一些判断:

int a = age==null? 0 : (int) a;
//或者
int a = age ?? 0;
空合并运算符(??)
用于定义可空类型和引用类型的默认值。
如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。
例如:a??b 当a为null时则返回b,a不为null时则返回a本身。
空合并运算符为右结合运算符,即操作时从右向左进行组合的。
如,“a??b??c”的形式按“a??(b??c)”计算。

参考:https://blog.csdn.net/weixin_38404507/article/details/108513074

运行结果:

{"Date":"2022-08-30T00:00:00+08:00","TemperatureCelsius":25,"Summary":"Hot"}

代码示例二:

using System.Text.Json;

namespace SerializeExtra
{
    /// <summary>
    /// 天气预测类
    /// </summary>
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        public string? SummaryField;
        public IList<DateTimeOffset>? DatesAvailable { get; set; }
        // 包含有一个字典
        public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
        //包含有一个数组
        public string[]? SummaryWords { get; set; }
    }
    //高低温度类
    public class HighLowTemps
    {
        public int High { get; set; }
        public int Low { get; set; }
    }
    public class Program
    {
        public static void Main()
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2022-08-30"),
                TemperatureCelsius = 25,
                Summary = "Hot",
                SummaryField = "Hot",
                DatesAvailable = new List<DateTimeOffset>()
                    { DateTime.Parse("2022-08-30"), DateTime.Parse("2022-08-31") },
                TemperatureRanges = new Dictionary<string, HighLowTemps>
                {
                    ["Cold"] = new HighLowTemps { High = 20, Low = -10 },
                    ["Hot"] = new HighLowTemps { High = 60, Low = 20 }
                },
                SummaryWords = new[] { "Cool", "Windy", "Humid" }
            };
            var options = new JsonSerializerOptions { WriteIndented = true };
            //将对象转换为JSON
            string jsonString = JsonSerializer.Serialize(weatherForecast, options);
            //保存JSON文件
            String path = @"G:\\Desktop\\archive1\\WeatherForecast.json";
            StreamWriter fileInfo = new StreamWriter(path);
            fileInfo.Write(jsonString);  
            fileInfo.Close();
            Console.WriteLine(jsonString);
        }
    }
}

运行结果

{
  "Date": "2022-08-30T00:00:00+08:00",
  "TemperatureCelsius": 25,
  "Summary": "Hot",
  "DatesAvailable": [
    "2022-08-30T00:00:00+08:00",
    "2022-08-31T00:00:00+08:00"
  ],
  "TemperatureRanges": {
    "Cold": {
      "High": 20,
      "Low": -10
    },
    "Hot": {
      "High": 60,
      "Low": 20
    }
  },
  "SummaryWords": [
    "Cool",
    "Windy",
    "Humid"
  ]
}
3.2 Json反序列化

代码示例

//天气类
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
        public string? SummaryField;
        public IList<DateTimeOffset>? DatesAvailable { get; set; }
        public Dictionary<string, HighLowTemps>? TemperatureRanges { get; set; }
        public string[]? SummaryWords { get; set; }
    }

    public class HighLowTemps
    {
        public int High { get; set; }
        public int Low { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            String jsonString = File.ReadAllText(@"G:\\Desktop\\archive1\\WeatherForecast.json");
            WeatherForecast? weatherForecast =
                JsonSerializer.Deserialize<WeatherForecast>(jsonString);
            Console.WriteLine($"Date: {weatherForecast?.Date}");
            Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
            Console.WriteLine($"Summary: {weatherForecast?.Summary}");
        }
    }

运行结果

Date: 2022/8/30 0:00:00 +08:00
TemperatureCelsius: 25
Summary: Hot

下一篇继续讲解二进制序列化
【C#进阶八】C#中的序列化与反序列化下(二进制序列化、XML序列化及JSON序列化)
参考资料:
https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/
欢迎关注公众号【智能建造小硕】(分享计算机编程、人工智能、智能建造、日常学习和科研经验等,欢迎大家关注交流。)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#二进制序列序列是一种将对象转换为二进制数据流以便存储或传输,并且可以将二进制数据流还原为对象的过程。这种序列方式可以用于在不同平台或不同应用程序之间传递对象数据。 在C#,可以使用BinaryFormatter类来二进制序列序列操作。下面是一个简单的示例: ```csharp using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] public class Person { public string Name { get; set; } public int Age { get; set; } } public class Program { public static void Main() { // 创建一个Person对象 Person person = new Person { Name = "Alice", Age = 25 }; // 将对象序列二进制数据流 BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, person); // 将二进制数据流序列为对象 stream.Position = 0; Person deserializedPerson = (Person)formatter.Deserialize(stream); // 输出序列后的对象属性 Console.WriteLine($"Name: {deserializedPerson.Name}, Age: {deserializedPerson.Age}"); } } ``` 在上面的示例,我们定义了一个名为Person的类,并使用[Serializable]特性标记该类可以序列。然后,我们创建了一个Person对象,并使用BinaryFormatter类将其序列二进制数据流。接着,我们将二进制数据流序列为一个新的Person对象,并输出其属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智能建造小硕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值