序列化和反序列化

待序列化的类(结构体)

 

[Serializable]
 public class MyObject
 {
  public int n1 = 0;
  public int n2 = 0;
  public String str = null;
 }

 

1.序列化 并存储在 dat文件中

string filename = "D://MyFile.dat";

 

MyObject obj = new MyObject();
   obj.n1 = 1;
   obj.n2 = 24;
   obj.str = "一些字符串";

//将obj类序列化


   IFormatter formatter = new BinaryFormatter();   
   Stream stream = new FileStream(filename, FileMode.Create,
    FileAccess.Write, FileShare.None);
   formatter.Serialize(stream, obj);
   stream.Close();

IFormatter: 位于 System.Runtime.Serialization下. 提供序列化格式的功能

BinaryFormatter():使用2进制格式序列化.

FileStream: 公开以文件为主的 Stream,既支持同步读写操作,也支持异步读写操作。

FileMode:指定操作系统打开文件的方式。

FileAccess:定义用于控制对文件的读访问、写访问或读/写访问的常数。

FileShare:包含用于控制其他 FileStream 对象对同一文件可以具有的访问类型的常数

formatter.Serialize():执行序列化

 

2.反序列化

//打开文件.执行反序列化

IFormatter formatter = new BinaryFormatter();
   Stream stream = new FileStream(filename, FileMode.Open,
    FileAccess.Read, FileShare.Read);
   MyObject obj = (MyObject) formatter.Deserialize(stream);
   MessageBox.Show(obj.str);
   stream.Close();

 

 

 

 

 

[转]C# 类的序列化与反序列化 XML 的实现

2008-02-20 11:51

 

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Xml.Serialization;

namespace ComLib.Model

{

    /// <summary>

    /// 公司信息

    /// </summary>

    public class ProductInfo

    {

        /// <summary>

        /// 公司

        /// </summary>

        public string Company = "";

        /// <summary>

        /// 联系人

        /// </summary>

        public string Linkman = "";

        /// <summary>

        /// 移动电话

        /// </summary>

        public string MobilePhone = "";

        /// <summary>

        /// 维护者

        /// </summary>

        public string Vindicator = "";

        /// <summary>

        /// 维护者手机

        /// </summary>

        public string VindicatorMobilePhone = "";

        /// <summary>

        /// 保修起始时间

        /// </summary>

        public DateTime MaintainStartTime = DateTime.Now.AddYears(-10);

        /// <summary>

        /// 保修终止时间

        /// </summary>

        public DateTime MaintainEndTime = DateTime.Now.AddYears(-10);

        /// <summary>

        /// 最后维修时间

        /// </summary>

        public DateTime LastMaintainTime = DateTime.Now.AddYears(-10);

        /// <summary>

        /// 反序列化XML字符串为对象

        /// </summary>

        /// <param name="xmlSource"></param>

        /// <returns></returns>

        public static ProductInfo Deserialize(string xmlSource)

        {

           

            ProductInfo obj = new ProductInfo();

            if (xmlSource.Trim() == "") return obj;

            try

            {

                XmlSerializer x = new XmlSerializer(typeof(ProductInfo));

                Stream stream = Protocol.ProtocolHelper.GetStream(xmlSource);

                stream.Seek(0, SeekOrigin.Begin);

                obj = (ProductInfo)x.Deserialize(stream);

                stream.Close();

            }

            catch

            { }

            return obj;

        }

        /// <summary>

        /// 序列化为XML字符串

        /// </summary>

        /// <returns></returns>

        public string Serialize()

        {

            string strSource = "";

            try

            {

                XmlSerializer s = new XmlSerializer(typeof(ProductInfo));

                Stream stream = new MemoryStream();

                s.Serialize(stream, this);

                stream.Seek(0, SeekOrigin.Begin); //这一点非常重要 否则无法读取

                using (StreamReader reader = new StreamReader(stream))

                {

                    // Just read to the end.

                    strSource = reader.ReadToEnd();

                }

            }

            catch { }

            return strSource;

        }

    }

}

------------------------------------------

C#对象序列化的基本使用

2007-12-10 10:05

 

       今天在写程序的时候,想要保存一些对象。最初设计时的想法是才用xml来保存。

实际编程过程中发现这还是挺繁琐的,那么多的字段和属性,还有各种组合的类。如果用xml来保存,嵌套多,嫌麻烦!

        最重要的是,我觉得使用XML来保存东西的话,那程序就被写死了,在保存/读取的时候,必须依据指定的元素的名或者属性名什么的来操作。如果使用序列化,那所有的一切交给Serialzer来做就搞定了。我们只需要写很少的代码就可以完成这个工作。

         然后考虑使用xml序列化来保存,但是这XmlSerialzer只能保存公共字段,感觉有些不够,就用二进制序列化了。对于某个需要进行序列化工作的类,在不继承自接口ISerializable的情况下,通过增加[Serializable]属性可以允许该类可以被序列化,如:

[Serializable]

public class Car

{

         private ArrayList _wheels=new ArrayList();

         private ArrayList _Lights=new ArrayList();

         public ArrayList Wheels

         {

               get{

                   return _wheels;

              }

               set{

                    _wheels=value;

              }

         }

         public ArrayList Lights

          {

              get{

                   return _Lights;

              }

              set{

                   _Lights=value;

              }

         }

          public Car

         {

              Wheel LeftWheel=new Wheel();

              Wheel RightWheel=new Wheel();

               _wheels.Add(LeftWheel);

              _wheels.Add(RightWheel);

  

               Light LeftLight=new Light();

              Light RightLight=new Light();

              _Lights.Add(LeftLight);

              _Lights.Add(RightLight);

         }

}

[Serialzable]

public class Wheel

{

     public float Radius=0.5f;

}

[Serailzable]

public class Light

{

     public float Price=200f;

}

序列化操作:

Car myCar=new Car();

FileStream fs=null;

try

{

     FileStream fs=new FileStream(@"../../Test.dat",FileMode.Create);

     BinaryFormatter bf=new BinaryFormatter();

     bf.Serialize(fs,myCar);

}

catch(Exception e)

{

     Messagebox.Show(e.Message);

}

finally

{

     if(fs!=null)

          fs.Close();

}

ArrayList是支持序列化的,通过以上操作,myCar实例的数据都被保存到了Test.dat中。

如果需要加载,则只需要反序列化:

   Car myCar=(Car)bf.Deserialize(fs);

  

对于多重继承情况,使用序列化还是很方便的,尽管看起来比较傻。

子类的序列化操作在父类里完成,由于不可能给this赋值,所以再在子类里操作父类里没有的字段。

如Car的父类,Vehicle

public abstract class Vehicle

{

     private float _Weight;

     private float _Height;

     private float _Length;

     public float Weight

     {

           get{return _Weight;}

          set{_Weight=value;}

     }

     public float Height

     {

          get{return _Height;}

           set{_Height=value;}

     }

     public float Length

     {

           get{retrun _Length;}

          set{_Length=value;}

     }

     //在这里反序列化

     public virtual Vehicle LoadFromFile(string filename)

     {

      //反序列化后给属性赋值

      obj=(Vehicle)bf.Deserialze(fs);

       _Weight=obj.Weight;

      _Length=obj.Length;

      _Height=obj.Height;

  

      return (Vehicle)obj;

      }

}

在子类Car里

public override Vehicle LoadFromFile(string filename)

{

      //如果可以this=(Car)base.LoadFromFile(filename);那就好了,可以省很多。

      Car car=(Car)base.LoadFromFile(filename);

      _Wheels=car.Wheels;

      _Lights=car.Lights;

      return null;

}

子类Track

public override Vehicle LoadFromFile(string filename)

{

      Track track=(Track)base.LoadFromFile(filename);

      _Capacity=track.Capacity;

}

  

有了这些,在构造函数中,就可以直接从文件中加载了。

public Car()

{

}

public Car(string filename)

{

     LoadFromFile(filename);

}

对于某些不支持序列化操作的对象或者结构,MSDN中说Serialzer会自动辨别,只要无法序列化,会自动标记成

[NonSerialzable],通过实际操作,发现还是需要手工标记。如:

[NonSerialzable]

private Microsoft.DirectX.Direct3D.Device pDevice;

如果对象里的不可序列化字段占据了绝大部分,那也就没有什么必要进行序列化了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值