C#中的序列化和反序列化小例

  在很多过关的游戏中,玩家打开游戏的时候还可以从上一次关闭的游戏关卡继续进行。上一次游戏退出的级别信息一般需要两种方式进行存储:数据库和磁盘文件。

  如果游戏软件本身并不大,使用数据库保存信息就显得太繁琐,而且成本很高,要玩一个小游戏,还要安装一个数据库,这样做法实在是很不值。可以采取保存到文件的做法:

  保存到对象状态到文件的代码:

<span style="font-size:18px;">  public class Game//游戏类
    {
        private string player;
        public string Player {
            get { return player; }
            set { player = value; } 
        }
        private int  level;
        public int Level
        {
            get { return level; }
            set { level = value; }
        }
    }</span>

<span style="font-size:18px;">//保存当前玩家的游戏名称和级别
        private void btnExit_Click(object sender, EventArgs e)
        {
            
            Game game = new Game();
            game.Player = "xiaoming";
            game.Level = 2;

            FileStream fs = new FileStream(@"game.bak", FileMode.OpenOrCreate, FileAccess.Write);

            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(game.Player);
            sw.WriteLine(game.Level);
            sw.Flush();
            sw.Close();
            Application.Exit();

        }</span>

<span style="font-size:18px;">//从文件读取上次保存的信息
        private void btnLoad_Click(object sender, EventArgs e)
        {
            Game game = new Game();
            FileStream fs = new FileStream(@"game.bak", FileMode.Open, FileAccess.Read);

            StreamReader sr = new StreamReader(fs);

            game.Player = sr.ReadLine();
            game.Level = int.Parse(sr.ReadLine());
            sr.Close();
            MessageBox.Show(game.Player + "最近一次的游戏级别为:" + game.Level);

          
        } </span>

  但是这种方式在实际开发中很不合适,如果对象的属性和方法很多,这样的读写文件,不仅工作量大,而且很容易处错误,(读取的顺序要和写入的顺序保持完全一致)

  .Net提供了序列化和反序列化的方法。使开发人员方便的将对象状态永久的存储到各种终端设备中,并快速的读取出来。

  使用序列化和反序列化后的代码:

<span style="font-size:18px;"> [Serializable ]//序列化和反序列化的对象,其类型必须添加<span style="font-family: Arial, Helvetica, sans-serif;">[Serializable ]特性</span>

    public class Game//游戏类
    {
        private string player;
        public string Player {
            get { return player; }
            set { player = value; } 
        }
        private int  level;
        public int Level
        {
            get { return level; }
            set { level = value; }
        }
    }</span>
<span style="font-size:18px;"> //保存当前玩家的游戏名称和级别
        private void btnExit_Click(object sender, EventArgs e)
        {
            
            Game game = new Game();
            game.Player = "xiaoming";
            game.Level = 2;

            FileStream fs = new FileStream("game.bin", FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();
            //使用Serialize方法将对象保存到主文件中
            formatter.Serialize(fs, game);
            Application.Exit();
        }</span>
<span style="font-size:18px;"> //从文件读取上次保存的信息
        private void btnLoad_Click(object sender, EventArgs e)
        {
         
<span style="white-space:pre">	</span>    Game game = null;
            FileStream fs = new FileStream(@"game.bin", FileMode.Open, FileAccess.Read);
            BinaryFormatter formatter = new BinaryFormatter();
            game = (Game)formatter.Deserialize(fs);
            MessageBox.Show(game.Player +"最近一次的游戏级别为:"+game.Level );
        } </span>

  序列化的步骤:

  1.添加 using System.Runtime.Serialization.Formatters.Binary;
  2.创建 文件流FileStream 对象

  3.实例化 BinaryFormatter 对象

  4.调用 BinaryFormatter 类的Serialize方法实现序列化

  反序列化的步骤:

  1.添加 using System.Runtime.Serialization.Formatters.Binary;
  2.创建 文件流FileStream 对象

  3.实例化 BinaryFormatter 对象

  4.调用BinaryFormatter类的Deserialize方法实现反序列化



using System; //需要用到MemoryStream using System.IO; using UnityEngine; //引入ProtoBuf命名空间 using ProtoBuf; /// /// 测试类 /// public class TestProtobuf : MonoBehaviour { /// /// 用于测试的数据类 /// [ProtoContract] //声明这个类能被序列化 public class UserData { //声明每一个需要被序列化的成员,编号从1开始 [ProtoMember(1)] public int id; [ProtoMember(2)] public string name; [ProtoMember(3)] public int level; } //测试代码 void Start() { //将要被序列化的UserData示例 UserData user1 = new UserData (); user1.id = 1; user1.name = "User1"; user1.level = 10; //打印user1 Debug.Log (string.Format ("user1-> id:{0}, name:{1}, level:{2}", user1.id, user1.name, user1.level)); //序列化 byte[] buff = null; using (MemoryStream ms = new MemoryStream ()) { Serializer.Serialize (ms, user1); ms.Position = 0; int length = (int)ms.Length; buff = new byte[length]; ms.Read (buff, 0, length); } //输出字节数组 Debug.Log (string.Format("Serialized data-> {0}", BitConverter.ToString(buff))); //反序列化 UserData user2 = default(UserData); using (MemoryStream ms = new MemoryStream (buff)) { user2 = Serializer.Deserialize (ms); } //打印反序列化生成的user2 Debug.Log (string.Format ("user2-> id:{0}, name:{1}, level:{2}", user2.id, user2.name, user2.level)); } } 作者:qufangliu 链接:https://www.jianshu.com/p/d9be1b3d2446 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值