Unity数据持久化——二进制

441 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情

学习2进制读写数据的原因

之前我们学过的xml和json都是用特定的字符串组合规则来读写数据的。 清晰易懂是他们的共同好处,但是也是一把双刃剑,比如如果我们用xml或者json存储数据,只要玩家找到对应的存储信息,就能够快速修改其中的内容。而且由于他们把数据转换成了对应的xml或者json字符串,我们最终在存储数据时存储的都是字符串数据,在读写时效率较低,内存和硬盘空间占用较大。总的来说就是xmljson安全性和效率较低。

Json、Xml好处是看着易懂,但是不好就是玩家可以找到存储信息,然后快速修改内容,另外因为xml和json是字符串,存取时候读写时的效率较低,内存和硬盘空间占用较大。Json、Xml 的坏处就是,不安全、效率低。所以二进制安全、效率高。

举个例子:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//所有需要保存的数据声明在这个类,其他脚本调用时声明实例即可;
[System.Serializable]
public class Save
{
    public float posX;
    public float posY;
}
BinaryFormatte序列化:

将对象转化成二进制,BinaryFormatte[反序列化]就是将二进制转化为对象。

命名空间:

System.Runtime.Serialization.Formatters;  

常用的两个方法:

Deserialize(Stream)     //将指定的流反序列化成对象
Serialize(Stream,Object)     //将对象序列化到给定的流

常用的两个属性:

Serializable     //表示可以被序列化
NonSerializable     //屏蔽被序列化

举个例子:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.UI;
public class DataManager : MonoBehaviour
{
    public Text t;
    public static string path;
    public string pathname = "my_path.bin";

    [System.Serializable]
    public class Zhuan_ye
    {
        public int ID;
        public string name;
        public List<Ban_ji> ban_ji = new List<Ban_ji>();
    }
    [System.Serializable]
    public class Ban_ji
    {
        public int ID;
        public string name;
        public int studentNumber;
    }

    private void Awake()
    {
        //班级
        List<Ban_ji> ban_jis = new List<Ban_ji>();
        for (int i = 0; i < 5; i++)
        {
            Ban_ji ban_ji=new Ban_ji();
            ban_ji.ID = i + 1;
            ban_ji.name = "name:" + (i + 1);
            ban_ji.studentNumber = i;
            ban_jis.Add(ban_ji);
        }

       Zhuan_ye zhuan_ye=new Zhuan_ye();
       zhuan_ye.ID = 100;
       zhuan_ye.name = "yaogaoshang";
       zhuan_ye.ban_ji = ban_jis;

        SaveBin(zhuan_ye);
        ReadS();

    }
    /// <summary>
    /// 将获取的二进制文件中的对象打印出来
    /// </summary>
    void ReadS()
    {
        Zhuan_ye zhuan_Ye = OpenBin();

        print("专业:" + zhuan_Ye.ID + "   " + zhuan_Ye.name);
        List<Ban_ji> BANS = zhuan_Ye.ban_ji;
        foreach (Ban_ji item in BANS)
        {
            print("\n");
            print(item.ID + "--" + item.name + "---" + item.studentNumber);
        }
    }
    /// <summary>
    /// 将对象存储在一个二进制文件中
    /// </summary>
    private void SaveBin(Zhuan_ye zhuan_ye)
    {
        try
        {
            path = getpath();
            FileStream file = null;
            BinaryFormatter bf = new BinaryFormatter();
            file = File.Open(path, FileMode.Create);
            bf.Serialize(file, zhuan_ye);
            file.Close();
            print("成功存储");
        }
        catch (System.Exception ex)
        {
           Debug.LogError("存储失败----"+ex.Message);
        }
        //string.IsNullOrEmpty(path):基本等价与path==null||path.length==0::没用到,但想到。

    }
    /// <summary>
    /// 返回二进制文件的反序列化对象
    /// </summary>
    /// <returns>The bin.</returns>
    public Zhuan_ye OpenBin()
    {
        path = getpath();
        Zhuan_ye zhuan_ye = null;
        FileStream file = null;
        BinaryFormatter bf = new BinaryFormatter();
        file = File.Open(path, FileMode.Open);
        zhuan_ye = (Zhuan_ye)bf.Deserialize(file);
        file.Close();
        return zhuan_ye;
    }
    /// <summary>
    /// 相对路径
    /// </summary>
    /// <returns>The getpath.</returns>
    public string getpath()
    {
        path = Application.dataPath + "/" +pathname;
        return path;
    }
}