当前位置: 首页 > news >正文

Unity_数据持久化_XML序列化与反序列化

Unity数据持久化

三、XML数据持久化

3.4 XML序列化与反序列化

3.4.1 序列化基础概念

序列化定义:
序列化是把对象转化为可传输的字节序列过程称为序列化。

反序列化定义:
反序列化是把字节序列还原为对象的过程称为反序列化。

通俗解释:

  • 序列化:把想要存储的内容转换为字节序列用于存储或传递
  • 反序列化:把存储或收到的字节序列信息解析读取出来使用

核心理解:
序列化就是将内存中的对象转换为可以存储或传输的格式,反序列化则是将这个格式重新转换回内存中的对象。

3.4.2 XML序列化核心知识点

XML序列化流程:

1. 第一步:准备一个数据结构类

// 定义要序列化的数据结构
public class Lesson1Test
{public string name = "张三";public int age = 25;public float height = 1.75f;public bool isStudent = true;// 无参构造函数(序列化需要)public Lesson1Test() { }
}// 创建对象实例
Lesson1Test lt = new Lesson1Test();

2. 第二步:进行序列化

// 关键知识点
// XmlSerializer 用于序列化对象为XML的关键类
// StreamWriter 用于存储文件
// using 用于方便流对象释放和销毁// 第一步:确定存储路径
string path = Application.persistentDataPath + "/Lesson1Test.xml";
print(Application.persistentDataPath);// 第二步:结合 using知识点 和 StreamWriter这个流对象来写入文件
// 括号内的代码:写入一个文件流 如果有该文件直接打开并修改如果没有该文件直接新建一个文件
// using 的新用法 括号当中包裹的声明的对象 会在大括号语句块结束后自动释放掉
// 当语句块结束 会自动帮助我们调用对象的 Dispose这个方法让其进行销毁
// using一般都是配合 内存占用比较大或者有读写操作时进行使用的
using (StreamWriter stream = new StreamWriter(path))
{// 第三步:进行xml文件序列化// 这句代码的含义就是通过序列化对象对我们类对象进行翻译 将其翻译成我们的xml文件写入到对应的文件// 第一个参数:文件流对象// 第二个参数:想要被翻译的对象// 注意:翻译机器的类型一定要和传入的对象是一致的不然会报错XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));s.Serialize(stream, lt);
}
3.4.3 实用XML序列化示例

基于实际项目的XML序列化实现:

using UnityEngine;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;/// <summary>
/// 文本数据类 - 包含各种数据类型
/// </summary>
public class TextData
{public string text = "gsffs";public int age;public List<string> list;public int[] array = new int[3] { 1, 2, 3 };// 无参构造函数(序列化需要)public TextData() { }
}/// <summary>
/// XML序列化实用示例类
/// 演示完整的序列化和反序列化流程
/// </summary>
public class XmlSerilizef : MonoBehaviour
{void Start(){// 确定存储路径string path = Application.persistentDataPath + "/TextData.xml";print("存储路径: " + path);// 创建测试数据TextData textData = new TextData();textData.list = new List<string>() { "1", "2", "3" };textData.age = 25;// 序列化对象到XML文件SerializeToXml(textData, path);// 从XML文件反序列化对象TextData textData2 = DeserializeFromXml(path);// 验证反序列化结果if (textData2 != null){print("反序列化成功!");print("文本: " + textData2.text);print("年龄: " + textData2.age);// 遍历列表数据print("列表内容:");foreach (string s in textData2.list){print(s);}// 遍历数组数据print("数组内容:");foreach (int i in textData2.array){print(i);}}}/// <summary>/// 序列化对象到XML文件/// </summary>/// <param name="data">要序列化的对象</param>/// <param name="path">文件路径</param>private void SerializeToXml(TextData data, string path){try{// 创建XmlSerializer实例XmlSerializer ser = new XmlSerializer(typeof(TextData));// 使用using语句确保资源正确释放using (StreamWriter sw = new StreamWriter(path)){ser.Serialize(sw, data);}print("序列化成功!");}catch (System.Exception e){print("序列化失败: " + e.Message);}}/// <summary>/// 从XML文件反序列化对象/// </summary>/// <param name="path">文件路径</param>/// <returns>反序列化的对象</returns>private TextData DeserializeFromXml(string path){try{// 创建XmlSerializer实例XmlSerializer ser = new XmlSerializer(typeof(TextData));// 使用using语句确保资源正确释放using (StreamReader sr = new StreamReader(path)){TextData data = (TextData)ser.Deserialize(sr);return data;}}catch (System.Exception e){print("反序列化失败: " + e.Message);return null;}}
}

关键知识点解析:

1. 数据类型支持

public class TextData
{public string text;        // 字符串类型public int age;           // 整数类型public List<string> list; // 列表类型public int[] array;       // 数组类型
}

2. 序列化流程

// 第一步:创建XmlSerializer实例
XmlSerializer ser = new XmlSerializer(typeof(TextData));// 第二步:使用StreamWriter写入文件
using (StreamWriter sw = new StreamWriter(path))
{// 第三步:执行序列化ser.Serialize(sw, data);
}

3. 反序列化流程

// 第一步:创建XmlSerializer实例
XmlSerializer ser = new XmlSerializer(typeof(TextData));// 第二步:使用StreamReader读取文件
using (StreamReader sr = new StreamReader(path))
{// 第三步:执行反序列化TextData data = (TextData)ser.Deserialize(sr);
}
3.4.4 XML序列化完整示例

完整的XML序列化实现:

using UnityEngine;
using System.Xml.Serialization;
using System.IO;/// <summary>
/// XML序列化示例类
/// 演示如何使用XmlSerializer进行对象序列化和反序列化
/// </summary>
public class XmlSerializationExample : MonoBehaviour
{void Start(){// 创建测试数据Lesson1Test testData = new Lesson1Test();// 序列化对象到XML文件SerializeToXml(testData);// 从XML文件反序列化对象Lesson1Test loadedData = DeserializeFromXml();// 验证反序列化结果if(loadedData != null){Debug.Log("姓名: " + loadedData.name);Debug.Log("年龄: " + loadedData.age);Debug.Log("身高: " + loadedData.height);Debug.Log("是否学生: " + loadedData.isStudent);}}/// <summary>/// 序列化对象到XML文件/// </summary>/// <param name="data">要序列化的对象</param>private void SerializeToXml(Lesson1Test data){// 确定存储路径string path = Application.persistentDataPath + "/Lesson1Test.xml";Debug.Log("存储路径: " + path);try{// 使用using语句确保资源正确释放using (StreamWriter stream = new StreamWriter(path)){// 创建XmlSerializer实例XmlSerializer serializer = new XmlSerializer(typeof(Lesson1Test));// 执行序列化serializer.Serialize(stream, data);Debug.Log("序列化成功,文件已保存到: " + path);}}catch (System.Exception e){Debug.LogError("序列化失败: " + e.Message);}}/// <summary>/// 从XML文件反序列化对象/// </summary>/// <returns>反序列化的对象</returns>private Lesson1Test DeserializeFromXml(){string path = Application.persistentDataPath + "/Lesson1Test.xml";// 检查文件是否存在if (!File.Exists(path)){Debug.LogWarning("XML文件不存在: " + path);return null;}try{// 使用using语句确保资源正确释放using (StreamReader stream = new StreamReader(path)){// 创建XmlSerializer实例XmlSerializer serializer = new XmlSerializer(typeof(Lesson1Test));// 执行反序列化Lesson1Test data = (Lesson1Test)serializer.Deserialize(stream);Debug.Log("反序列化成功");return data;}}catch (System.Exception e){Debug.LogError("反序列化失败: " + e.Message);return null;}}
}/// <summary>
/// 测试数据结构类
/// </summary>
[System.Serializable]
public class Lesson1Test
{// 基本数据类型public string name = "张三";public int age = 25;public float height = 1.75f;public bool isStudent = true;// 数组类型public int[] scores = { 85, 90, 78, 92, 88 };// 列表类型public List<string> hobbies = new List<string> { "读书", "游戏", "运动" };// 无参构造函数(序列化需要)public Lesson1Test() { }// 有参构造函数public Lesson1Test(string name, int age, float height){this.name = name;this.age = age;this.height = height;}
}
3.4.4 XML序列化总结

序列化流程:

  1. 有一个想要保存的类对象
  2. 使用XmlSerializer序列化该对象
  3. 通过StreamWriter配合using将数据存储写入文件

重要注意事项:

1. 只能序列化公共成员

public class TestClass
{public string publicField;     // 可以序列化private string privateField;   // 不能序列化public string PublicProperty { get; set; }  // 可以序列化private string PrivateProperty { get; set; } // 不能序列化
}

2. 不支持字典序列化

public class TestClass
{public List<string> list;      // 可以序列化public Dictionary<string, int> dict; // 不能直接序列化
}

3. 可以通过特性修改节点信息或者设置属性信息

public class TestClass
{[XmlElement("PlayerName")]  // 修改XML节点名称public string name;[XmlAttribute("PlayerAge")] // 将字段作为属性存储public int age;[XmlIgnore]  // 忽略此字段,不进行序列化public string tempData;
}

4. Stream相关要配合using使用

// 正确的使用方式
using (StreamWriter stream = new StreamWriter(path))
{XmlSerializer serializer = new XmlSerializer(typeof(TestClass));serializer.Serialize(stream, data);
}// 错误的使用方式(可能导致资源泄漏)
StreamWriter stream = new StreamWriter(path);
XmlSerializer serializer = new XmlSerializer(typeof(TestClass));
serializer.Serialize(stream, data);
// 忘记调用stream.Close()或stream.Dispose()

5. 必须有无参构造函数

public class TestClass
{public string name;public int age;// 必须有无参构造函数,否则序列化会失败public TestClass() { }// 可以有其他构造函数public TestClass(string name, int age){this.name = name;this.age = age;}
}

6. 类型一致性要求

// 序列化和反序列化时,类型必须完全一致
XmlSerializer ser = new XmlSerializer(typeof(TextData)); // 类型必须匹配
TextData data = (TextData)ser.Deserialize(stream);      // 强制转换类型

1. 只能序列化公共成员

public class TestClass
{public string publicField;     // 可以序列化private string privateField;   // 不能序列化public string PublicProperty { get; set; }  // 可以序列化private string PrivateProperty { get; set; } // 不能序列化
}

2. 不支持字典序列化

public class TestClass
{public List<string> list;      // 可以序列化public Dictionary<string, int> dict; // 不能直接序列化
}

3. 可以通过特性修改节点信息或者设置属性信息

public class TestClass
{[XmlElement("PlayerName")]  // 修改XML节点名称public string name;[XmlAttribute("PlayerAge")] // 将字段作为属性存储public int age;[XmlIgnore]  // 忽略此字段,不进行序列化public string tempData;
}

4. Stream相关要配合using使用

// 正确的使用方式
using (StreamWriter stream = new StreamWriter(path))
{XmlSerializer serializer = new XmlSerializer(typeof(TestClass));serializer.Serialize(stream, data);
}// 错误的使用方式(可能导致资源泄漏)
StreamWriter stream = new StreamWriter(path);
XmlSerializer serializer = new XmlSerializer(typeof(TestClass));
serializer.Serialize(stream, data);
// 忘记调用stream.Close()或stream.Dispose()
3.4.5 XML序列化高级特性

1. 自定义XML节点名称

public class PlayerData
{[XmlElement("PlayerName")]public string name;[XmlElement("PlayerLevel")]public int level;[XmlElement("PlayerClass")]public string playerClass;
}

2. 使用XML属性存储数据

public class ItemData
{[XmlAttribute("ItemID")]public int id;[XmlAttribute("ItemName")]public string name;[XmlAttribute("ItemCount")]public int count;
}

3. 忽略特定字段

public class GameData
{public string playerName;public int score;[XmlIgnore]public string temporaryData; // 不会被序列化[XmlIgnore]public System.DateTime lastSaveTime; // 不会被序列化
}

4. 处理复杂数据结构

public class GameSaveData
{public PlayerInfo playerInfo;public List<ItemInfo> inventory;public GameSettings settings;public GameSaveData(){playerInfo = new PlayerInfo();inventory = new List<ItemInfo>();settings = new GameSettings();}
}public class PlayerInfo
{public string name;public int level;public float experience;
}public class ItemInfo
{[XmlAttribute("ID")]public int id;[XmlAttribute("Count")]public int count;
}public class GameSettings
{public float musicVolume;public float soundVolume;public bool fullscreen;
}
http://www.dtcms.com/a/312628.html

相关文章:

  • 设计模式学习[17]---组合模式
  • Android 之 RxJava2
  • 电商系统定制开发流程:ZKmall开源商城需求分析到上线全程可控
  • Node.js (Express) + MySQL + Redis构建项目流程
  • C++ 入门基础(3)
  • 从零开始学Express,理解服务器,路由于中间件
  • Ubuntu20.04 Carla安装与和Ros联合仿真
  • OpenCV轻松入门_面向python(第一章OpenCV入门)
  • Kafka——怎么重设消费者组位移?
  • 北京-4年功能测试2年空窗-报培训班学测开-第六十六天
  • 「iOS」————属性关键字底层原理
  • Jupyter Notebook 中高效处理和实时展示来自 OpenCV 和 Pillow 的图像数据探究
  • 网络缓冲区的设计以及C++实现
  • 【Python练习】075. 编写一个函数,实现简单的语音识别功能
  • 项目日记---高并发内存池整体框架
  • 人工智能与医疗健康:AI 助力医疗的新格局
  • 信号传播速度与延时
  • [硬件电路-143]:模拟电路 - 开关电源与线性稳压电源的详细比较
  • PLC传感器接线与输出信号接线
  • Redis实战(7)-- 高级特性 Redis Stream数据结构与基础命令
  • 【0基础PS】PS工具详解--文字工具
  • .NET 开源节点编辑器,将你的程序功能模块节点化
  • pytorch 安装
  • Paxos 算法是什么?介绍 RAFT 和 ZAB,以及它们之间的区别?会有脑裂问题吗?为什么?
  • 算法竞赛阶段二-数据结构(39)数据结构栈模拟实现
  • AI陪伴赛道,热闹背后是真需求还是泡沫?
  • 应急响应整理
  • Back to the Features:附录A
  • [创业之路-532]:知识、技能、技术、科学各自解决什么问题?
  • 手机(电脑)与音响的蓝牙通信