C# 二進制讀寫與序列化和反序列化

可參考雨松大神:
http://www.xuanyusong.com/archives/1919
http://www.xuanyusong.com/archives/1901

文章將實現數據存儲爲二進制文件,然後通過二進制文件解析數據。

二進制文件讀寫操作:

        //寫入二進制文件
        public static void WriteByteValues()
        {
            string fileName = @"C:\Test.dat" 

            if (File.Exists(fileName))
                File.Delete(fileName);

            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);

            bw.Write(1.250F);
            bw.Write(@"c:\Test");
            bw.Write(10);
            bw.Write(true);

            bw.Close();
            fs.Close();
        }

        //讀取二進制文件
        public static void ReadByteValues()
        {
            if (File.Exists(fileName))
            {
                string fileName = @"C:\Test.dat" 

                FileStream fs = new FileStream(fileName, FileMode.Open);
                BinaryReader br = new BinaryReader(fs);

                Console.WriteLine(br.ReadSingle());
                Console.WriteLine(br.ReadString());
                Console.WriteLine(br.ReadInt32());
                Console.WriteLine(br.ReadBoolean());

                fs.Close();
                br.Close();
            }
        }

測試:

        static void Main(string[] args)
        {
            WriteByteValues();
            ReadByteValues();
            Console.ReadKey();
        }

二進制序列化和反序列化操作:

    [Serializable]
    public class Car
    {
        private Radio radio;
        public string CarName { get; set; }
        public string OwnerOfCar { get; set; }
    }

    [Serializable]
    public class ChineseCar : Car
    {
        public int MaxSpeed { set; get; }
        public bool CanFly { set; get; }
    }

    [Serializable]
    public class Radio
    {
        [NonSerialized] public string radioID = "XF-552RR6";
        public bool hasTweeters;
    }
        //序列化
        public static void WriteSerializer(object obj, string filename)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using (FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                try
                {
                    binaryFormatter.Serialize(fileStream, obj);
                }
                catch (Exception)
                {
                    Console.WriteLine("fail");
                    throw;
                }
            }
        }
        //反序列化
        public static void ReadDeSerializer(string filename)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using (FileStream fileStream = File.OpenRead(filename))
            {
                ChineseCar result = binaryFormatter.Deserialize(fileStream) as ChineseCar;
                Console.WriteLine(result.CanFly);
                Console.WriteLine(result.MaxSpeed);
                Console.WriteLine(result.CarName);
                Console.WriteLine(result.OwnerOfCar);
            }
        }

測試:

        static void Main(string[] args)
        {
            ChineseCar myCar = new ChineseCar()
            {
                CanFly = false,
                MaxSpeed = 200,
                CarName = "Fly Man",
                OwnerOfCar = "阿童木"
            };

            BeginChangeTObinary(myCar, fileName);
            ShowBinaryFile(fileName);
            Console.ReadKey();
        }

上文中都是使用的是文件流,信息都會被寫在文件中,產生額外的文件。
接下來使用內存流,信息都會被寫進內存中,不會產生額外的文件。


二進制內存流讀寫操作:

        static void TestMemoryStream()
        {
            //如果使用文件流,則信息會被寫進文件中  
            //而使用內存流,則信息會被寫進內存中,不會產生額外的文件  
            MemoryStream ms = new MemoryStream();
            //將待寫入的數據從字符串轉換爲字節數組   
            byte[] testBytes = Encoding.UTF8.GetBytes("測試數據");

            PrintInfo(ms);

            ms.Write(testBytes, 0, testBytes.Length);
            PrintInfo(ms);

            //SeekOrigin的三種取值:  
            //1.Begin 指定流的開頭 2.Current 指定流內的當前位置 3.End 指定流的結尾  
            //將position重定位爲開頭  
            ms.Seek(0, SeekOrigin.Begin);
            byte[] bytes = new byte[testBytes.Length];
            ms.Read(bytes, 0, bytes.Length);
            Console.WriteLine("bytes:{0}", Encoding.UTF8.GetString(bytes, 0, bytes.Length));
            PrintInfo(ms);

            byte[] buffer = ms.GetBuffer();
            Console.WriteLine("buffer:{0}", Encoding.UTF8.GetString(buffer, 0, buffer.Length));
            PrintInfo(ms);
        }

        static void PrintInfo(MemoryStream ms)
        {
            Console.WriteLine("Capacity:{0}", ms.Capacity);
            Console.WriteLine("Length:{0}", ms.Length);
            Console.WriteLine("Position:{0}", ms.Position);
            Console.WriteLine();
        }

        static void TestBinaryReaderWriter()
        {
            MemoryStream ms = new MemoryStream();
            BinaryReader br = new BinaryReader(ms);
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write("helloworld");
            ms.Seek(0, SeekOrigin.Begin);
            string s = br.ReadString();
            Console.WriteLine("content:{0}", s);

            //字符串的長度是可變的,因此無法確定字符串的字節數  
            //當使用BinaryWriter.Write寫入字符串時,會用第一位來存儲字符串的長度  
            ms.Seek(0, SeekOrigin.Begin);
            byte[] bytes = ms.ToArray();
            for (int i = 0; i < bytes.Length; i++)
            {
                Console.WriteLine("content1:{0}", bytes[i]);
            }
        }

參考http://blog.csdn.net/pengze0902/article/details/53366271

二進制內存流序列化和反序列化操作:

        /// <summary>
        /// 將對象序列化爲byte[]
        /// 使用IFormatter的Serialize序列化
        /// </summary>
        /// <param name="obj">需要序列化的對象</param>
        /// <returns>序列化獲取的二進制流</returns>
        public static byte[] FormatterObjectBytes(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");
            byte[] buff;
            try
            {
                using (var ms = new MemoryStream())
                {
                    IFormatter iFormatter = new BinaryFormatter();
                    iFormatter.Serialize(ms, obj);
                    buff = ms.GetBuffer();
                    Console.WriteLine("buff:{0}", Encoding.UTF8.GetString(buff, 0, buff.Length));
                }
            }
            catch (Exception er)
            {
                throw new Exception(er.Message);
            }
            return buff;
        }
        /// <summary>
        ///將byte[]反序列化爲對象
        /// </summary>
        /// <param name="buff"></param>
        /// <returns></returns>
        public static object FormatterByteObject(byte[] buff)
        {
            if (buff == null)
                throw new ArgumentNullException("buff");
            object obj;
            try
            {
                using (var ms = new MemoryStream(buff))
                {
                    IFormatter iFormatter = new BinaryFormatter();
                    obj = iFormatter.Deserialize(ms);
                }
            }
            catch (Exception er)
            {
                throw new Exception(er.Message);
            }
            return obj;
        }

測試:

        static void Main(string[] args)
        {
            ChineseCar myCar = new ChineseCar()
            {
                CanFly = false,
                MaxSpeed = 200,
                CarName = "Fly Man",
                OwnerOfCar = "阿童木"
            };

            OperatorByte.BeginChangeTObinary(myCar, fileName);
            OperatorByte.ShowBinaryFile(fileName);
            byte[] buff = OperatorByte.FormatterObjectBytes(myCar);
            ChineseCar car = OperatorByte.FormatterByteObject(buff) as ChineseCar;

            Console.WriteLine(car.CanFly);
            Console.WriteLine(car.MaxSpeed);
            Console.WriteLine(car.CarName);
            Console.WriteLine(car.OwnerOfCar);
            Console.ReadKey();
        }

好了,祝進步。

每天進步一點點。

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