C#序列化與反序列化學習筆記

    本筆記摘抄自:https://www.cnblogs.com/maitian-lf/p/3670570.html,記錄一下學習過程以備後續查用。

    序列化是把一個內存中的對象的信息轉化成一個可以持久化保存的形式,以便於保存或傳輸。序列化的主要作用是不同平臺之間進行通信,常用的序

列化有json、xml、文件等,下面就逐個講下這三種序列化的方法。

    一、序列化爲json

    C#中用於對象和json相互轉換的原生類有兩個:DataContractJsonSerializer和JavaScriptSerializer,其中JavaScriptSerializer主要用於web瀏覽器和服

務器之間的通信。這裏主要講DataContractJsonSerializer的使用,要使用DataContractJsonSerializer,先要在項目中引用System.Runtime.Serialization。

    首先準備一個測試的類Book:

class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        class Book
        {
            [DataMember]
            public int ID { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
        }
    }
View Code

    [DataContract]指定該類型要定義或實現一個數據協定,並可由序列化程序(如System.Runtime.Serialization.DataContractSerializer)進行序列化。

    [DataMember]當應用於類型的成員時,指定該成員是數據協定的一部分並可由System.Runtime.Serialization.DataContractSerializer進行序列化。

    首先創建一個Book對象,然後實例化一個DataContractJsonSerializer實例,最後用該實例的WriteObject()方法將對象寫到流中,代碼如下:

class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region 對象序列化爲json
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            //序列化爲json
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Book));
            using (MemoryStream stream = new MemoryStream())
            {
                jsonSerializer.WriteObject(stream, book);
                string result = Encoding.UTF8.GetString(stream.ToArray());
                Console.WriteLine(result);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    將一個json格式的字符串反序列化爲對象是用DataContractJsonSerializer實例的ReadObject()方法,代碼如下:

class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region json反序列化爲對象
            Book book = new Book();
            //json反序列化爲對象
            string oriStr = "{\"Id\":101,\"Name\":\"C#程序設計\",\"Price\":79.5}";
            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Book));
            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(oriStr)))
            {
                Book outBook = jsonSerializer.ReadObject(stream) as Book;
                Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    我們也可以把上面的json序列化與反序列爲封裝成泛型方法,這樣可以公用,全部代碼如下:

class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        public class SerializerHelper
        {
            /// 將對象序列化爲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 = 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(Encoding.UTF8.GetBytes(json)))
                {
                    T result = formatter.ReadObject(stream) as T;
                    return result;
                }
            }
        }

        static void Main(string[] args)
        {
            #region json序列化與反序列化泛型方法
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            //對象序列化爲json
            string result = SerializerHelper.ObjectToJson(book);
            Console.WriteLine(result);

            //json反序列化爲對象
            string oriStr = "{\"Id\":101,\"Name\":\"C#程序設計\",\"Price\":79.5}";
            Book outBook = SerializerHelper.JsonToObject<Book>(oriStr);
            Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");

            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    二、序列化爲xml

    C#中將對象序列化和反序列化爲xml的類是XmlSerializer,要引用System.Xml.Serialization。

    首先創建一個XmlSerializer對象實例,然後用實例的Serialize方法將對象寫入到文件流中,代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region 對象序列化爲xml(文件流)
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Book));
            using (FileStream stream = new FileStream(@"E:\book.xml", FileMode.OpenOrCreate))
            {
                xmlSerializer.Serialize(stream, book);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    程序運行後會在c盤產生一個book.xml文件,內容如下:

<?xml version="1.0"?>
<Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>101</Id>
  <Name>C#程序設計</Name>
  <Price>79.5</Price>
</Book>

    當然也可以將對象轉換成對象流,然後轉換成xml格式的字符串,代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region 對象序列化爲xml(對象流)
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Book));
            using (MemoryStream stream = new MemoryStream())
            {
                xmlSerializer.Serialize(stream, book);
                string result = Encoding.UTF8.GetString(stream.ToArray());  //轉換成xml字符串
                Console.WriteLine(result);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    將xml文件反序列化的方法是用XmlSerializer實例的Deserialize()方法,代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region xml文件反序列化爲對象
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Book));
            using (FileStream stream = new FileStream(@"E:\book.xml", FileMode.OpenOrCreate))
            {
                XmlReader xmlReader = new XmlTextReader(stream);
                Book outBook = xmlSerializer.Deserialize(xmlReader) as Book;//反序列化
                Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    我們同樣也可以把上面的xml序列化與反序列爲封裝成泛型方法,這樣可以公用,全部代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        /// <summary>
        /// 序列化反序列化幫助類
        /// </summary>
        public class SerializerHelper
        {
            /// <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 = 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;
                }
            }
        }

        static void Main(string[] args)
        {
            #region xml序列化與反序列化泛型方法
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            //對象序列化爲xml
            SerializerHelper.ObjectToXml(book, @"E:\book.xml");

            //xml反序列化爲對象
            Book outBook = SerializerHelper.XmlToObject(book, @"E:\book.xml");
            Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");

            Console.Read();
            #endregion
        }
    }
View Code

    三、序列化爲二進制文件

    C#中將對象序列化和反序列化爲二進制文件的類是BinaryFormatter,要引用System.Runtime.Serialization.Formatters.Binary,另外Book類頭要加

[Serializable]屬性。

    先創建一個BinaryFormatter對象實例,然後用實例的Serialize的方法將對象寫入到文件流中,代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        [Serializable]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region 對象序列化爲二進制文件
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            //對象序列化爲二進制文件
            BinaryFormatter formatter = new BinaryFormatter();
            using (FileStream stream = new FileStream(@"E:\book.txt", FileMode.OpenOrCreate))
            {
                formatter.Serialize(stream, book);
            }
            Console.Read();
            #endregion
        }
    }
View Code

    可以通過BinaryFormatter類型實例的Deserialize()方法把二進制文本反序列化爲對象,代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        [Serializable]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        static void Main(string[] args)
        {
            #region 將二進制文件反序列化爲對象
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };

            //序列化文件
            BinaryFormatter formatter = new BinaryFormatter();
            using (FileStream stream = new FileStream(@"E:\book.txt", FileMode.OpenOrCreate))
            {
                Book outBook = formatter.Deserialize(stream) as Book;
                Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");
            }
            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

    我們同樣也可以把序列化和把序列化爲二進制文件的方法封裝成泛型方法,全部代碼如下:

public class Program
    {
        /// <summary>
        /// Book類
        /// </summary>
        [DataContract]
        [Serializable]
        public class Book
        {
            [DataMember]
            public int Id { get; set; }

            [DataMember]
            public string Name { get; set; }

            [DataMember]
            public float Price { get; set; }
        }

        /// <summary>
        /// 序列化反序列化幫助類
        /// </summary>
        public class SerializerHelper
        {
            #region 二進制文件序列化反序列化
            /// <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 = Encoding.UTF8.GetString(stream.ToArray());
                    return result;
                }
            }

            /// <summary>
            /// 將對象序列化爲二進制文件
            /// </summary>
            /// <typeparam name="T">類型</typeparam>
            /// <param name="t">實例</param>
            /// <param name="path">存放路徑</param>
            public static void ObjectToBinaryFile<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 = Encoding.UTF8.GetBytes(s);
                BinaryFormatter formatter = new BinaryFormatter();
                using (MemoryStream stream = new MemoryStream(buffer))
                {
                    T result = formatter.Deserialize(stream) as T;
                    return result;
                }
            }

            /// <summary>
            /// 將二進制文件反序列化爲對象
            /// </summary>
            /// <typeparam name="T">類型</typeparam>
            /// <param name="path">路徑</param>
            /// <returns>對象</returns>
            public static T BinaryFileToObject<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;
                }
            }
            #endregion
        }

        static void Main(string[] args)
        {
            #region 二進制文件序列化反序列化泛型方法
            Book book = new Book() { Id = 101, Name = "C#程序設計", Price = 79.5f };
            //對象序列化爲二進制文件
            SerializerHelper.ObjectToBinaryFile(book, @"E:\book.txt");

            //二進制文件反序列化爲對象
            Book outBook = SerializerHelper.BinaryFileToObject<Book>(@"E:\book.txt") as Book;
            Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}");

            Console.Read();
            #endregion
        }
    }
View Code

    運行結果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章