• Unity中的【格式化数据】进行【系列化】和【反系列化】操作


    数据的存储和传输往往都是以字节码的形式进行,那么,在Unity中,如何把格式化的列表转成字节码,然后又把字节码恢复成原本来格式化数据呢?

    注意:用 System.Runtime.Serialization.Formatters.Binary 进行系列化和反系列化的时候,反系列化时会报错:提示找不到某某版本的程序集。
    比如:Unity的exe作为客户端,它把信息传送到服务器[winForm]上,当服务器反系列化的时候,因为程序集的版本不一致,导致报错。更通用的做法就是把对象系列化成Json
    大致流程如下:Object -> Json -> UTF8 -> byte[] -> 网络传输 byte[] -> UTF8 -> Json -> Object

    一、【格式化数据】的【系列化】和【反系列化】

    在这里插入图片描述

    二、【系列化】和【反系列化】的关键要点

    • 1、主要引用的包
    using System.Runtime.Serialization.Formatters.Binary;
    
    • 1
    • 2、系列化的function
    BinaryFormatter.Serialize(stream对象,数据对象);
    
    • 1
    • 3、反系列化的function
     BinaryFormatter.Deserialize(stream对象);
    
    • 1
    • 4、其它知识:内存流对象MemoryStream与字节数组byte[]的转换
    List<byte> buffer = new List<byte>();
    
    • 1

    stream to byte[]

    MemoryStream stream = new MemoryStream();            //内存流对象
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, sendData);
    buffer.AddRange(stream.ToArray());
    
    • 1
    • 2
    • 3
    • 4

    byte[] to stream

    MemoryStream stream2 = new MemoryStream(buffer.ToArray());
    
    • 1

    三、Unity中的服用方法

    在这里插入图片描述

    四、demo代码

    • 测试环境 win10 + unity2020.3 in UnityEditor
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    using System;
    
    /// 
    /// 实验数据
    /// 
    [Serializable]
    public class SendData
    {
        [SerializeField]
        public string resproCode;
        [SerializeField]
        public int status;
        [SerializeField]
        public int score;
        [SerializeField]
        public long startTime;
        [SerializeField]
        public long endTime;
        [SerializeField]
        public List<StepData> steps = new List<StepData>();
    }
    /// 
    /// 实验步骤
    /// 
    [Serializable]
    public class StepData
    {
        [SerializeField] public int seq;
        [SerializeField] public string title;
        [SerializeField] public long startTime;
        [SerializeField] public long endTime;
        [SerializeField] public int expectTime;
        [SerializeField] public int maxScore;
        [SerializeField] public int score;
        [SerializeField] public int repeatCount;
        [SerializeField] public string evaluation;
        [SerializeField] public string scoringModel;
        [SerializeField] public string remarks;
    }
    
    public class Deserilize : MonoBehaviour
    {
        /// 
        /// 测试按钮:系列化和反系列化
        /// 
        public Button btnTest;
    
        /// 
        /// 系列化前的表
        /// 
        [Header("【1】要系列化的对象")]
        public SendData sendData;
    
        /// 
        /// 字节码
        /// 
        [Header("【2】用来传输或者存储的字节码")]
        public byte[] serBytes;
    
        /// 
        /// 反系列化后的表
        /// 
        [Header("【3】反系列化后恢复的对象")]
        public SendData deSendData;
    
        // Start is called before the first frame update
        void Start()
        {
            //按钮事件绑定
            btnTest.onClick.AddListener(() =>
                {
                    List<byte> buffer = new List<byte>();
    
                    //【1】系列化
                    buffer.AddRange(Serialize(sendData));
    
                    //【2】字节码数据
                    serBytes = buffer.ToArray();
    
                    //【3】......数据存储和传输
    
                    //【4】反系列化
                    //Debug.Log("======反系列化=======");              
                    var res = DeSerialize<SendData>(serBytes);   
                    Debug.Log("总分数:" + res.resproCode);
                    Debug.Log("步骤数量:" + res.steps.Count);
                    deSendData = res;
                });
        }
    
        /// 
        ///系列化:把某个类型的数据对象dataToSerialize转换成字节数组byte[]
        /// 
        /// 数据对象的数据类型
        /// 数据对象
        /// 字节数组
        public static byte[] Serialize<T>(T dataToSerialize)
        {       
            MemoryStream stream = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, dataToSerialize); 
            return stream.ToArray();
        }
    
        /// 
        /// 反系列化:把字节数组byte[]恢复成指定类型T的数据
        /// 
        /// 反系列化恢复成什么类型的数据
        /// 字节数组
        /// 指定类型的数据
        public static T DeSerialize<T>(byte[] bytesAry)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream2 = new MemoryStream(bytesAry);
            return (T)formatter.Deserialize(stream2);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
  • 相关阅读:
    idea中哪些快捷键对工作帮助比较大?
    Nginx配置全局https
    两万字盘点被玩烂了的9种设计模式
    springboot215基于springboot技术的美食烹饪互动平台的设计与实现
    基于边缘智能网关的储充一体电站管理方案
    考研C语言复习进阶(2)
    读书笔记:《次第花开》
    差分数组(定义+性质+证明+代码实现+巩固练习)
    react项目配置(类组件、函数式组件)
    Ajax学习:Ajax发送POST请求
  • 原文地址:https://blog.csdn.net/dzj2021/article/details/126708107