序列化是什么?常見的序列化方式有哪些?什么時候我們會用到序列化?

序列化(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.pswp.cn/bicheng/72006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72006.shtml
英文地址,請注明出處:http://en.pswp.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&…