序列化是什么?常见的序列化方式有哪些?什么时候我们会用到序列化?

序列化(Serialization)是指将对象的状态信息转换为可以存储或传输的形式(如字节序列、XML 文档、JSON 字符串等)的过程。反序列化则是序列化的逆过程,它将存储或接收到的字节序列、XML 文档、JSON 字符串等转换回对象的状态信息。通过序列化,对象可以在不同的环境中进行持久化存储或网络传输,而反序列化则可以让接收方恢复出原始的对象。

目录

常见的序列化方式

1. JSON 序列化

数据类型支持(JsonUtility不支持循环引用)

LitJson

使用场景

1. 数据存储

2. 网络通信

3. 配置文件

2.XML 序列化

3. 二进制序列化


常见的序列化方式

1. JSON 序列化

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有良好的可读性和跨语言性。它以键值对的形式组织数据,易于人类阅读和编写,也易于机器解析和生成。

Unity 内置了 JsonUtility 类用于简单的 JSON 序列化和反序列化,但功能相对有限。可以使用litJson.(LitJson 功能强大但使用相对复杂,适合处理复杂的数据结构和有特殊需求的场景;而 Unity 内置的 JsonUtility 简单易用,性能较好,适合处理简单的数据结构。与 Unity 内置的 JsonUtility 相比,LitJson 在使用时通常不需要为类添加序列化特性

数据类型支持(JsonUtility不支持循环引用)
  • 基本数据类型JsonUtility 能很好地处理基本数据类型(如果对象之间存在循环引用,JsonUtility 会抛出异常),如 intfloatstring 等。
  • 自定义类和结构体:对于自定义类和结构体,类或结构体必须是公共的,且成员变量也必须是公共的,JsonUtility 才能正确序列化和反序列化。
  • 集合类型:可以处理数组和 List<T> 等集合类型,但嵌套集合需要注意结构的正确性。
LitJson
  • 强大的类型支持:能处理各种复杂的数据类型,包括嵌套对象、数组、字典等,并且对于自定义类和结构体的处理较为灵活,支持手动实现序列化和反序列化逻辑。
  • 自定义序列化:允许开发者自定义序列化和反序列化过程,可通过实现自定义的转换器来满足特殊需求,例如对日期格式的自定义处理。
  • 处理循环引用:具备一定的处理对象循环引用的能力,虽然可能需要额外的配置,但能应对复杂对象关系的序列化场景。
使用场景
1. 数据存储

将游戏中的配置数据、玩家进度等存储为 JSON 文件(实现数据持久化),方便后续读取和修改。

2. 网络通信

在网络通信中(在 Unity C# 的网络通信中,Newtonsoft.Json(Json.NET)是使用次数相对较多的序列化方案),将数据序列化为 JSON 格式进行传输,接收方再进行反序列化。

3. 配置文件

使用 JSON 文件作为游戏的配置文件,方便开发人员修改和管理。

由于使用这部分的功能在游戏开发过程之中可能是经常需要的,所以我们可以把Json的序列化和反序列化制作成Json模块的序列化反序列化功能框架。核心功能代码示例如下:

        private static readonly JsonType JsonTypes = JsonType.LitJson;public static void SaveData(object data, string fileName){string path = UnityEngine.Application.persistentDataPath + "/" + fileName + ".json";string jsonStr = "";switch (JsonTypes){case JsonType.JsonUtlity:jsonStr = JsonUtility.ToJson(data);break;case JsonType.LitJson:jsonStr = JsonMapper.ToJson(data);break;}File.WriteAllText(path,jsonStr);}public static T LoadData<T>(string fileName) where T : new(){string path = UnityEngine.Application.streamingAssetsPath + "/" + fileName + ".json";if (!File.Exists(path)) path = UnityEngine.Application.persistentDataPath + "/" + fileName + ".json";if (!File.Exists(path)) return new T();string jsonStr = File.ReadAllText(path);T data = default(T);switch (JsonTypes){case JsonType.JsonUtlity:data = JsonUtility.FromJson<T>(jsonStr);break;case JsonType.LitJson:data = JsonMapper.ToObject<T>(jsonStr);break;}return data;}

2.XML 序列化

XML(eXtensible Markup Language)是一种标记语言,用于存储和传输数据。它具有良好的结构化和扩展性,支持复杂的数据结构和元数据。

xml序列化的使用场景与json的使用场景相似,都是一种数据持久化的序列化方案,我们还可以使用xml制作配置文件书写一些编辑器小工具的功能。例如生成消息类等。

  • 若要使用 System.Xml.Serialization.XmlSerializer 对自定义类进行序列化和反序列化,类必须是可序列化的。这意味着类及其所有公共字段都必须是可访问的,并且类要有无参构造函数。如果类包含私有字段,默认情况下这些字段不会被序列化,除非使用特性(如 [XmlElement])进行标记。
  • 可以使用 XML 相关的特性(如 [XmlRoot][XmlElement][XmlAttribute] 等)来控制 XML 元素和属性的生成。例如,[XmlRoot] 可以指定 XML 根元素的名称,[XmlElement] 可以指定 XML 元素的名称,[XmlAttribute] 可以将字段序列化为 XML 属性。
  • XML 文件的格式必须严格遵循 XML 规范,否则在解析时会抛出异常。在读取和解析 XML 文件时,要进行异常处理,以确保程序的健壮性。
  • 不同平台可能对文件编码有不同的默认设置,在保存和读取 XML 文件时,要明确指定编码格式,以确保数据的正确传输和解析。通常建议使用 UTF - 8 编码。

使用xml制作编辑器小工具的简单案例:自动生成脚本。(展示一部分)

        public void GenerateEnum(XmlNodeList list){string namespaceStr = "";string enumNameStr = "";string fieldStr = "";foreach (XmlNode enumNode in list){//获取命名空间配置信息namespaceStr = enumNode.Attributes?["namespace"].Value;//获取枚举名配置信息enumNameStr = enumNode.Attributes?["name"].Value;XmlNodeList enumFields = enumNode.SelectNodes("field");//一个新的枚举需要清空上一次拼接的字段字符串fieldStr = "";if (enumFields == null){Debug.Log("不存在field字段,请检查您的xml配置文件是否准确!");return;}foreach (XmlNode enumField in enumFields){fieldStr += "\t\t" + enumField.Attributes?["name"].Value;if (enumField.InnerText != "")fieldStr += "=" + enumField.InnerText;fieldStr += ",\r\n";}//对所有可变的内容进行拼接string enumStr = $"namespace {namespaceStr}\r\n" +"{\r\n" +$"\tpublic enum {enumNameStr}\r\n" +"\t{\r\n" +$"{fieldStr}" +"\t}\r\n" +"}";//保存文件的路径string path = _saveDataPath + namespaceStr + "/Enum/";if (!Directory.Exists(path))Directory.CreateDirectory(path);File.WriteAllText(path+enumNameStr+".cs",enumStr);}Debug.Log("枚举生成结束");}
        private static readonly GenerateCSharp generateCSharp = new();private static readonly string protoInfoPath = Application.dataPath + "/Scripts/Game/Editor/XmlTool/Net.xml";[MenuItem("ProtocolTool/生成C#脚本")]private static void GenerateCSharp(){//根据这些信息 拼接字符串 生成对应的脚本//生成对应枚举脚本generateCSharp.GenerateEnum(GetNodes("enum"));//生成对应的数据结构类脚本generateCSharp.GenerateData(GetNodes("data"));//生成对应消息类脚本generateCSharp.GenerateMsg(GetNodes("message"));//刷新编辑器界面AssetDatabase.Refresh();}

3. 二进制序列化

二进制序列化将对象转换为字节序列,这种方式通常比文本格式(如 JSON、XML)更紧凑,读写速度更快,但可读性较差。不同的编程语言有不同的二进制序列化机制。(常用于需要高效存储和传输大量数据的场景,如游戏开发、数据库系统等。

代码示例:

        /// <summary>/// 在游戏过程中存储的数据/// </summary>/// <param name="obj">读取类型</param>/// <param name="isNetworkTransmission">是否使用网络运输</param>/// <param name="isEncrypt">是否需要加密数据</param>/// <typeparam name="T"></typeparam>public void AutoCreatFile<T>(T obj,bool isNetworkTransmission=false,bool isEncrypt=true) where T:class{_key = (byte)UnityEngine.Random.Range(1f, 200f);string fileName = typeof(T).Name;if (!Directory.Exists(Application.dataPath + "/BinaryAutoScripts"))_rootFile = Directory.CreateDirectory(Application.dataPath + "/BinaryAutoScripts");if (!_passWordDic.ContainsKey(fileName) && isEncrypt)_passWordDic.Add(fileName,_key);else_passWordDic[fileName] = _key;BinaryFormatter bf = new BinaryFormatter();if (isNetworkTransmission){using var ms = new MemoryStream();bf.Serialize(ms, obj);byte[] bytes = ms.GetBuffer();if (isEncrypt)for (int i = 0; i < bytes.Length; i++)bytes[i] ^= _key;File.WriteAllBytes(Application.dataPath + $"/BinaryAutoScripts/{fileName}_Net.nicolepotter", bytes);}else{using var fs = new FileStream(Application.dataPath + $"/BinaryAutoScripts/{fileName}.nicolepotter", FileMode.OpenOrCreate, FileAccess.Write);bf.Serialize(fs, obj);fs.Flush();}
#if UNITY_EDITORAssetDatabase.Refresh();
#endif}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/72006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python解决“比赛配对”问题

Python解决“比赛配对”问题 问题描述测试样例解决思路代码 问题描述 小R正在组织一个比赛&#xff0c;比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制&#xff1a; 如果当前队伍数为 偶数&#xff0c;那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛&#xff0c;…

uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法

需求&#xff1a; 如下图&#xff0c;要实现左图的样式&#xff0c;先实现框架&#xff0c;文字到时候 往里填就行了&#xff0c;原来的解决方案是想用css,html来实现&#xff0c;发现实现起来蛮麻烦的。我也没找到合适的实现方法&#xff0c;最后换使用canvas来实现&#xff…

大模型与呼叫中心融合:未来发展的潜力何在?

大模型与呼叫中心的结合&#xff0c;为企业带来了前所未有的发展机遇。通过提升服务效率、优化营销效果、降低运营成本、增强数据管理与分析能力、提升客户体验以及推动行业创新与变革&#xff0c;大模型呼叫中心正在重塑客户服务与营销的未来。 大模型与呼叫中心的结合具有巨…

vue3+ts+uniapp+unibest 微信小程序(第二篇)—— 图文详解自定义背景图页面布局、普通页面布局、分页表单页面布局

文章目录 简介一、自定义背景图布局1.1 效果预览1.2 实现思路1.3 custom-page 组件全量代码1.4 页面使用 二、普通页面布局2.1 效果预览2.2 实现思路2.3 公共样式部分2.4 页面使用 三、分页表单页面布局3.1 效果预览3.2 实现思路3.3 页面代码 简介 开发工具&#xff1a;VsCode…

华为交换机堆叠方法

堆叠配置&#xff1a; 先把接口shutdown 第一台&#xff1a; int stack-port 0/1 port interface XGigabitEthernet0/0/3 enable y qu int stack-port 0/2 port interface XGigabitEthernet0/0/4 enable y qu stack slot 0 priority 200 y 第二台&#xff1a; int stack…

AI革命下的多元生态:DeepSeek、ChatGPT、XAI、文心一言与通义千问的行业渗透与场景重构

前言 人工智能技术的爆发式发展催生了多样化的AI模型生态&#xff0c;从通用对话到垂直领域应用&#xff0c;从数据挖掘到创意生成&#xff0c;各模型凭借其独特的技术优势与场景适配性&#xff0c;正在重塑全球产业格局。本文将以DeepSeek、ChatGPT、XAI&#xff08;可解释人…

nginx 配置https

参考文档&#xff1a;nginx 文档 -- nginx官网|nginx下载安装|nginx配置|nginx教程 配置 HTTPS 服务器 HTTPS 服务器优化 SSL 证书链 单个 HTTP/HTTPS 服务器 基于名称的 HTTPS 服务器 具有多个名称 的 SSL 证书 服务器名称指示 兼容性 要配置 HTTPS 服务器&#xff0c;ssl…

python-leetcode-乘积最大子数组

152. 乘积最大子数组 - 力扣&#xff08;LeetCode&#xff09; class Solution:def maxProduct(self, nums: List[int]) -> int:if not nums:return 0max_prod nums[0]min_prod nums[0]result nums[0]for i in range(1, len(nums)):if nums[i] < 0:max_prod, min_prod…

前端或者后端通常用到数组使用方式

第一个是:Array.from() 将具有length属性或者可迭代的对象转化为数组 Array.from(abcdef) // 返回值[a1, b1, c1, d1, e1, f1] Array.from(new Map([[b1, 1 ], [a1, 2 ]])) Array.from(new Set([ 1 , 2 , 3 ])) 第二个是:Array.reduce() 遍历数组,将函数的返回值,存储到累加器中…

最大子数组和力扣--53

目录 题目 思路 代码 题目 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1…

JavaScript 深浅拷贝全面解析

在 JavaScript 中&#xff0c;深浅拷贝是处理对象复制的重要概念。它们的核心区别在于对 引用类型数据 的处理方式&#xff0c;理解这一点对避免程序中的意外数据污染至关重要。 一、核心概念解析 1. 基本类型 vs 引用类型 基本类型&#xff1a;Number, String, Boolean, null…

【大模型】大模型推理能力深度剖析:从通用模型到专业优化

大模型推理能力深度剖析&#xff1a;从通用模型到专业优化 大模型推理能力深度剖析&#xff1a;从通用模型到专业优化一、通用语言模型与推理模型的区别&#xff08;一&#xff09;通用语言模型&#xff1a;多任务的“万金油”&#xff08;二&#xff09;推理模型&#xff1a;复…

RISC-V架构的平台级中断控制器(PLIC:platform-level interrupt controller)详解

英文缩写 英文缩写中文含义PLICplatform-level interrupt controller&#xff0c;平台级中断控制器SMTsimultaneous multi-threading&#xff0c;并发多线程HARTRISC-V架构中的硬件线程SMTsimultaneous multi-threading&#xff0c;多线程执行M-MODEmachine mode&#xff0c;机…

[Web 安全] PHP 反序列化漏洞 —— PHP 序列化 反序列化

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01&#xff1a;PHP 序列化 — Serialize 序列化就是将对象的状态信息转化为可以存储或传输的形式的过程&#xff0c;在 PHP 中&#xff0c;通常使用 serialize() 函数来完成序列化的操作…

航空装配自动化神器Ethercat转profient网关搭配机器人精准控制

生产管理系统通过网关与装配机器人连接&#xff0c;加快航空器机身的装配速度&#xff0c;减少人为误差。 航空制造对装配线的精度和效率有着极高的要求。某航空制造厂使用的耐达讯Profinet转EtherCAT协议网关NY-PN-ECATM&#xff0c;将其生产管理系统与装配机器人连接&#xf…

什么是MySql的主从复制(主从同步)?

主页还有其他面试题总结&#xff0c;有需要的可以去看一下&#xff0c;喜欢的就留个三连再走吧~ 1.什么是MySql的主从复制原理&#xff1f; 主从复制的核心就是二进制binlog&#xff08;DDL&#xff08;数据定义语言&#xff09;语句和DML&#xff08;数据操纵语言&#xff09…

自然语言处理:初识自然语言处理

介绍 大家好&#xff0c;博主又来给大家分享知识了。从这次开始&#xff0c;博主给大家分享自然语言处理这个领域的内容。这也是博主非常感兴趣的研究领域。 最开始&#xff0c;博主计划在自然语言处理系列的第一篇博文中&#xff0c;和大家聊聊文本规范化这个话题。毕竟在自…

【保姆级视频教程(二)】YOLOv12训练数据集构建:标签格式转换-划分-YAML 配置 避坑指南 | 小白也能轻松玩转目标检测!

【2025全站首发】YOLOv12训练数据集构建&#xff1a;标签格式转换-划分-YAML 配置 避坑指南 | 小白也能轻松玩转目标检测&#xff01; 文章目录 1. 数据集准备1.1 标签格式转换1.2 数据集划分1.3 yaml配置文件创建 2. 训练验证 1. 数据集准备 示例数据集下载链接&#xff1a;P…

【人工智能】蓝耘智算平台盛大发布DeepSeek满血版:开创AI推理体验新纪元

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀ 蓝耘智算平台 蓝耘智算平台核心技术与突破元生代推理引擎快速入门&#xff1a;三步调用大模型接口&#xff0c;OpenAI SDK无缝兼容实战用例文…

【网络编程】几个常用命令:ping / netstat / xargs / pidof / watch

ping&#xff1a;检测网络联通 1. ping 的基本功能2. ping 的工作原理3. ping 的常见用法4. ping 的输出解释5. ping 的应用场景6. 注意事项 netstat&#xff1a;查看网络状态 1. netstat 的基本功能2. 常见用法3. 示例4. 输出字段解释5. netstat 的替代工具6. 注意事项 xargs&…