zoukankan      html  css  js  c++  java
  • 序列化、反序列化XML和JSON对象常用的方式

    序列化、反序列化对象常用的两种方式

    序列化和反序列化对象常用的两种方式

    序列化是使用指定的格式将一个或多个对象转换为字节序列的过程。反序列化则是相反的过程。

    我们这里记录2个常用的序列化和反序列化方法。

    1、序列化为XML

    2、系列化为JSON

    一、序列化和反序列化XML

    1.1、序列化XML

    创建一个WPF程序。

    新建一个类文件命名为Person,同时我们引用以下名称空间,创建Person的类中的属性,

    使用[XmlAtribute("fname")]属性,会把按当前类属性从子节点变为当前节点的属性,文件大小就变小了。可以尝试一下去掉和不去掉之后产生的XML是否一样。

    using System;                        //DateTime
    using System.Collections.Generic;    //List<T>,HashSet<T>
    using System.Xml.Serialization;      //XmlSerializer
    
    namespace SerializationAndDeserialization
    {
        public class Person
        {
            public Person()
            {
    
            }
            public Person(decimal initialSalary)
            {
                Salary = initialSalary;
            }
            [XmlAttribute("fname")]
            public string FirstName { get; set; }
            [XmlAttribute("lname")]
            public string LastName { get; set; }
            [XmlAttribute("dob")]
            public DateTime DateOfBirth { get; set; }
            public HashSet<Person> Children { get; set; }
            protected decimal Salary { get; set; } 
        }
    }
    
    

    在MainWindow.cs文件中我们在构造函数中实例化Person。序列化到文件中,然后再反序列化回来。同时我们观察使用XmlAttribute和不使用XmlAttribute有什么差别、观察属性定义为public类型和protected类型再序列化和反序列化过程中有什么不同。

    using System;
    using System.Collections.Generic; 
    using System.Xml.Serialization;
    using System.IO;
    using System.Windows;
    using static System.Console;
    using static System.Environment;
    using static System.IO.Path;
    
    namespace SerializationAndDeserialization
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                var people = new List<Person>()
                {
                    new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
                    new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
                    new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
                    { FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
                };
                var xs = new XmlSerializer(typeof(List<Person>));
                string path = Combine(CurrentDirectory, "pepple.xaml");
                using (FileStream stream = File.Create(path))
                {
                    xs.Serialize(stream, people);
                }
                WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
                WriteLine();
                WriteLine(File.ReadAllText(path));
                //系列化文件中不包含Salary,因为是Protected类型。
                //引用System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性。文件结构就改变了,同时文件变小了。
            }
        }  
    }
    
    

    左边是不使用再类属性上添加 [XmlAttribute("")]的方法生成的xml文件。右侧是使用 [XmlAttribute("")]属性。右侧文件小了很多。

    1.2、反序列化XML

    我们现在反序列化这个XML文件。

    我们添加代码后完整代码如下:

    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.IO;
    using System.Windows;
    using static System.Console;
    using static System.Environment;
    using static System.IO.Path;
    
    namespace SerializationAndDeserialization
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                var people = new List<Person>()
                {
                    new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
                    new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
                    new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
                    { FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
                };
                var xs = new XmlSerializer(typeof(List<Person>));
                string path = Combine(CurrentDirectory, "pepple.xaml");
                using (FileStream stream = File.Create(path))
                {
                    xs.Serialize(stream, people);
                }
                WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
                WriteLine();
                WriteLine(File.ReadAllText(path));
                //系列化文件中不包含Salary,因为是Protected类型。
                //引用System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性。文件结构就改变了,同时文件变小了。
    
                //反序列化
                using (FileStream xmlLoad = File.Open(path, FileMode.Open))
                {
                    var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad); 
                    foreach (var item in loadedPeople)
                    {
                        WriteLine($"{item.LastName} has {item.Children.Count} children.");
                    }
                }
    
            }
        }
    }
    
    

    点击运行,我们观察VS的输出中这三行Log。我们的反序列化就完成了。

    Smith has 0 children.
    Jone has 0 children.
    Cox has 1 children.
    

    二、序列化和反序列化JSON

    使用JSON序列化格式的最流行的.NET库之一是Newtonsoft.Json,又名Json.NET。

    我们再项目右键点击弹出菜单中选择管理NuGet包,点击浏览输入Newtonsoft.Json。选中找到的Newtonsoft.Json,点击安装。

    2.1、尝试序列化信息为JSON,并存放到文本文件中。

    我们再后面添加如下代码

    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.IO;
    using System.Windows;
    using static System.Console;
    using static System.Environment;
    using static System.IO.Path;
    
    namespace SerializationAndDeserialization
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                var people = new List<Person>()
                {
                    new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
                    new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
                    new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
                    { FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
                };
                var xs = new XmlSerializer(typeof(List<Person>));
                string path = Combine(CurrentDirectory, "pepple.xaml");
                using (FileStream stream = File.Create(path))
                {
                    xs.Serialize(stream, people);
                }
                WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
                WriteLine();
                WriteLine(File.ReadAllText(path));
                //系列化文件中不包含Salary,因为是Protected类型。
                //引用System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性。文件结构就改变了,同时文件变小了。
    
                //反序列化
                using (FileStream xmlLoad = File.Open(path, FileMode.Open))
                {
                    var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
                    foreach (var item in loadedPeople)
                    {
                        WriteLine($"{item.LastName} has {item.Children.Count} children.");
                    }
                } 
    
                //序列化JSON
                string jsonPath = Combine(CurrentDirectory, "prople.json");
                using (StreamWriter jsonStream = File.CreateText(jsonPath))
                {
                    var jss = new Newtonsoft.Json.JsonSerializer();
                    jss.Serialize(jsonStream, people);
                }
                WriteLine();
                WriteLine($"Written {new FileInfo(jsonPath).Length} bytes of JSON to :{jsonPath}");
                WriteLine(File.ReadAllText(jsonPath));
    
            }
        }
    }
    
    

    调试运行输出找到Log关键行如下。

    Written 365 bytes of JSON to :E:C#NotesWPF技巧SerializationAndDeserializationSerializationAndDeserializationinDebugprople.json
    [{"FirstName":"Alice","LastName":"Smith","DateOfBirth":"1974-03-14T00:00:00","Children":null},{"FirstName":"Bob","LastName":"Jone","DateOfBirth":"1969-11-23T00:00:00","Children":null},{"FirstName":"Charlie","LastName":"Cox","DateOfBirth":"1984-05-04T00:00:00","Children":[{"FirstName":"Sally","LastName":"Cox","DateOfBirth":"2000-07-12T00:00:00","Children":null}]}]
    

    2.2反序列化JSON文件为对象

    反序列化的过程,我们使用File读取文件内容,然后使用JsonConvert.DeserializeObject 来反序列化到对象。具体代码如下:

    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.IO;
    using System.Windows;
    using static System.Console;
    using static System.Environment;
    using static System.IO.Path;
    using Newtonsoft.Json;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Diagnostics;
    
    namespace SerializationAndDeserialization
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                var people = new List<Person>()
                {
                    new Person(30000M){ FirstName="Alice",LastName="Smith",DateOfBirth=new DateTime(1974,3,14)},
                    new Person(40000M){ FirstName="Bob",LastName="Jone",DateOfBirth=new DateTime(1969,11,23)},
                    new Person(20000M){ FirstName="Charlie",LastName="Cox",DateOfBirth=new DateTime(1984,5,4),Children=new HashSet<Person>{ new Person(0M)
                    { FirstName="Sally",LastName="Cox",DateOfBirth=new DateTime(2000,7,12)} } }
                };
                //序列化XML
                var xs = new XmlSerializer(typeof(List<Person>));
                string path = Combine(CurrentDirectory, "pepple.xaml");
                using (FileStream stream = File.Create(path))
                {
                    xs.Serialize(stream, people);
                }
                WriteLine("Witeten {0:N0} bytes of XML to {1}", arg0: new FileInfo(path).Length, arg1: path);
                WriteLine();
                WriteLine(File.ReadAllText(path));
                //系列化文件中不包含Salary,因为是Protected类型。
                //引用System.Xml.Serialization后使用[XmlAtribute("fname")]添加特性。文件结构就改变了,同时文件变小了。
    
                //反序列化XML
                using (FileStream xmlLoad = File.Open(path, FileMode.Open))
                {
                    var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
                    foreach (var item in loadedPeople)
                    {
                        WriteLine($"{item.LastName} has {item.Children.Count} children.");
                    }
                }
    
                //序列化JSON
                string jsonPath = Combine(CurrentDirectory, "prople.json");
                using (StreamWriter jsonStream = File.CreateText(jsonPath))
                {
                    var jss = new Newtonsoft.Json.JsonSerializer();
                    jss.Serialize(jsonStream, people);
                }
                WriteLine();
                WriteLine($"Written {new FileInfo(jsonPath).Length} bytes of JSON to :{jsonPath}");
                //反序列化JSON
                var jsonStr = File.ReadAllText(jsonPath);
                WriteLine(File.ReadAllText(jsonPath));
                var persons = JsonConvert.DeserializeObject<List<Person>>(jsonStr);
                foreach (var item in persons)
                {
                    Debug.WriteLine(item.ToString());
                }
            }
        }
    }
    
    

    再Person中重写ToString()方法用于再反序列化结束后打印输出内容。

    using System;                        //DateTime
    using System.Collections.Generic;    //List<T>,HashSet<T>
    using System.Xml.Serialization;      //XmlSerializer
    
    namespace SerializationAndDeserialization
    {
        public class Person
        {
            public Person()
            {
    
            }
            public Person(decimal initialSalary)
            {
                Salary = initialSalary;
            }
            [XmlAttribute("fname")]
            public string FirstName { get; set; }
            [XmlAttribute("lname")]
            public string LastName { get; set; }
            [XmlAttribute("dob")]
            public DateTime DateOfBirth { get; set; }
            public HashSet<Person> Children { get; set; }
            protected decimal Salary { get; set; }
            public override string ToString()
            {
                return $"FirstName:{FirstName},LastName:{LastName},DateOfBirth:{DateOfBirth}";
            }
        }
    }
    
    

    整体代码如上,序列化xml和反序列化xml,序列化json和反序列化json都再上面。适用于NET Core之前的版本。Net Core之后的有System.Text.Json对象。

  • 相关阅读:
    tensorboard页面显示No dashboards are active for current data set 问题win10系统
    tensorboard在cmd运行成功但在浏览器中不能正常显示的问题解决
    使用tensorflow设计的网络模型看不到数据流向怎么办
    pycharm中某些方法被标黄的原因及解决办法
    np.newaxis()用法
    决策树模型、本质、连续值完整篇
    决策树模型、本质、连续值
    vsftp 用无法登陆的用户名登陆(也叫虚拟用户)并进入到自己的文件夹test
    vsftp 使用匿名帐号登陆
    CentOS 5/6.X 使用 EPEL YUM源
  • 原文地址:https://www.cnblogs.com/duwenlong/p/15325730.html
Copyright © 2011-2022 走看看