首页 > 其他分享 >Unity学习笔记--数据持久化XML文件(2)

Unity学习笔记--数据持久化XML文件(2)

时间:2023-12-01 17:00:26浏览次数:56  
标签:XML -- new Unity reader using XmlSerializer 序列化 public

IXmlSerializable接口:

使用该接口可以帮助处理不能被序列化和反序列化的特殊类得到处理,

使特殊类继承IXmlSerializable接口 ,实现其中的读写方法,检测到读写方法被重写之后,

便会按照自定义实现的接口来实现方法。

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using UnityEngine;

namespace Building.XML
{
    /// <summary>
    /// 要存储的类 实现IXMLSerializer接口
    /// </summary>
    public class Test03:IXmlSerializable
    {
        public int testInt;
        public string testName;
        public int age;
        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// 在进行读操作 反序列化时候调用的方法
        /// </summary>
        /// <param name="reader"></param>
        public void ReadXml(XmlReader reader)
        {
            //读XML文件
            //001 读属性
            testInt = int.Parse(reader["testInt"]);
            testName = reader["testName"];
            //002 读节点
            //单个读
            reader.Read();//读节点名称
            reader.Read();//读节点中内容
            //获取内容数值
            testInt = int.Parse(reader.Value);
            reader.Read();//读结尾
            
            //读下一个开始
            reader.Read();
            reader.Read();
            testName = reader.Value;
            reader.Read();
            //或者循环读
            //=====进行读  对应这要读取的XML文件
            /*while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                        case "testInt":
                            reader.Read();
                            testInt = int.Parse(reader.Value);
                            break;
                        case "testName":
                            reader.Read();
                            testName = reader.Value;
                            break;
                        case "testAge":
                            reader.Read();
                            age = int.Parse(reader.Value);
                            break;
                        
                    }
                }
            }
            */

            reader.Read();
            reader.Read();
            age = int.Parse(reader.Value);
            reader.Read();
            
            //003 读取包裹的元素节点
            XmlSerializer xmlSerializerInt = new XmlSerializer(typeof(int));
            XmlSerializer xmlSerializerString = new XmlSerializer(typeof(string));
            //跳过根节点--默认read停留在开始
            reader.Read();
            //读包裹开始
            reader.ReadStartElement("BlogName");
            //读包裹内容
            testName = xmlSerializerString.Deserialize(reader).ToString();
            reader.ReadEndElement();//读取包裹结束
            
            reader.ReadStartElement("Age");
            age = (int)xmlSerializerInt.Deserialize(reader);
            reader.ReadEndElement();
            
        }

        /// <summary>
        /// 在进行写操作 序列化时候调用的方法
        /// </summary>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void WriteXml(XmlWriter writer)
        {
            // 向XML文件中写内容
            //1 写属性
            writer.WriteAttributeString("testInt",testInt.ToString());
            writer.WriteAttributeString("testName",testName);
            
            //2 写节点
            writer.WriteElementString("testInt",this.testInt.ToString());
            testName = "TonyChang";
            age = 21;
            writer.WriteElementString("testName",testName);
            writer.WriteElementString("testAge",age.ToString());
            //3.写包裹的节点
            XmlSerializer serializerInt = new XmlSerializer(typeof(int));
            XmlSerializer serializerString = new XmlSerializer(typeof(string));
            
            writer.WriteStartElement("BlogName");//开始包裹
            serializerString.Serialize(writer,testName);//包裹中内容 序列化放到写入流中
            writer.WriteEndElement();//结束包裹
            
            writer.WriteStartElement("Age");
            serializerInt.Serialize(writer,age);
            writer.WriteEndElement();//结束包裹
        }
    }
    public class XMLDemo2:MonoBehaviour
    {
        private void Start()
        {
            //采用默认方式(上文中提到的)进行序列化与反序列化
            string path = Application.persistentDataPath + "/XMLDemo02.xml";
            Test03 test03 = new Test03();
            print(path);//打印存储路径
            using (StreamWriter streamWriter=new StreamWriter(path))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Test03));
                xmlSerializer.Serialize(streamWriter,test03);
            }
            
            //反序列化
            if (File.Exists(path))
            {
                using (StreamReader streamReader=new StreamReader(path))
                {
                    XmlSerializer xmlSerializerRead = new XmlSerializer(typeof(Test03));
                    Test03 test03Read = xmlSerializerRead.Deserialize(streamReader) as Test03;
                    print(test03.testName);
                    print(test03Read.age);
                }
            }
        }
    }
}

image-20231201134726377

存储的XML的文件样式(注意对照XML存储样式来理解读取和存储的代码)

特别注意在代码中的读取包裹节点时候先要跳过“根节点”,code Line81;

自定义实现支持序列化与反序列化的字典

using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace Building.XML.SerializerDic
{
    /// <summary>
    /// 支持序列化与反序列化的字典
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    public class SerializerDictionary<TKey,TValue>:Dictionary<TKey,TValue>,IXmlSerializable
    {
        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// 反序列化 读取XML文件调用
        /// </summary>
        /// <param name="reader"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void ReadXml(XmlReader reader)
        {
            //新建写入器 反序列化工具
            XmlSerializer xmlSerializerKey = new XmlSerializer(typeof(TKey));
            XmlSerializer xmlSerializerValue = new XmlSerializer(typeof(TValue));
            
            //跳过根节点
            reader.Read();
            
            while (reader.NodeType!=XmlNodeType.EndElement)
            {
                TKey tk = (TKey)xmlSerializerKey.Deserialize(reader);
                TValue tv = (TValue) xmlSerializerValue.Deserialize(reader);
                this.Add(tk,tv);//添加到容器中
            }
        }

        /// <summary>
        /// 序列化 写入XML文件时候调用
        /// </summary>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void WriteXml(XmlWriter writer)
        {
           //新建写入器 序列化工具
           XmlSerializer xmlSerializerKey = new XmlSerializer(typeof(TKey));
           XmlSerializer xmlSerializerValue = new XmlSerializer(typeof(TValue));

           foreach (KeyValuePair<TKey,TValue> kv in this)
           {
               xmlSerializerKey.Serialize(writer,kv.Key);
               xmlSerializerValue.Serialize(writer,kv.Value);
           }
        }
    }
}

测试代码:

using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

namespace Building.XML.SerializerDic
{
    public class Test4
    {
        public int num = 4;
        public SerializerDictionary<int, string> sDic;
    }
    public class XMLDemo3:MonoBehaviour
    {
        private void Start()
        {
            string path = Application.persistentDataPath + "/XMLDemo4.xml";
            print(path);
            Test4 test4 = new Test4();
            test4.sDic = new SerializerDictionary<int, string>() {{1, "Tony"}, {2, "Tom"}, {3, "Frank"}};
            using (StreamWriter streamWriter=new StreamWriter(path))
            {
                XmlSerializer xmlSerializerWrite = new XmlSerializer(typeof(Test4));
                xmlSerializerWrite.Serialize(streamWriter,test4);
            }
            
            //进行反序列化读取
            if (File.Exists(path))
            {
                using (StreamReader streamReader=new StreamReader(path))
                {
                    XmlSerializer xmlSerializerRead = new XmlSerializer(typeof(Test4));
                    Test4 test4Read=xmlSerializerRead.Deserialize(streamReader) as Test4;
                    foreach (KeyValuePair<int,string> pair in test4Read.sDic)
                    {
                       Debug.Log("key:"+pair.Key+",Value:"+pair.Value);
                    }
                }
            }
        }
    }
}

存储生成的XML文件内容:

image-20231201153332043

XML存储工具类:

using System;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

namespace Building.XML.SerializerDic
{
    public class XMLSerializerManager
    {
        private static XMLSerializerManager instance=new XMLSerializerManager();
        public  static XMLSerializerManager Instance=>instance;

        private XMLSerializerManager()
        {
        }
        /// <summary>
        /// 存储文件
        /// </summary>
        /// <param name="data">数据内容</param>
        /// <param name="FileName">存储文件名称</param>
        public void SaveData(object data, string FileName)
        {
            string path = Application.persistentDataPath + "/" + FileName + ".xml";
            using (StreamWriter streamWriter=new StreamWriter(path))
            {
                XmlSerializer xmlSerializerWriter = new XmlSerializer(data.GetType());
                xmlSerializerWriter.Serialize(streamWriter,data);
            }
        }
        public object LodaData(Type type,string FileName)
        {
            string path = Application.persistentDataPath + "/" + FileName + ".xml";
            if (!File.Exists(path))
            {
                path = Application.streamingAssetsPath + "/" + FileName + ".xml";
                if (!File.Exists(path))
                {
                    //如果在持续存储文件夹下未发现 并且在 流文件夹中仍旧未发现
                    //则利用反射返回一个该类型的实例 其中的数据为默认值
                    return Activator.CreateInstance(type);
                }
            }

            using (StreamReader streamReader=new StreamReader(path))
            {
                XmlSerializer xmlSerializerReader = new XmlSerializer(type);
                return xmlSerializerReader.Deserialize(streamReader);
            }
        }
    }
}

标签:XML,--,new,Unity,reader,using,XmlSerializer,序列化,public
From: https://www.cnblogs.com/TonyCode/p/17870456.html

相关文章

  • RTSP安防系统LiteCVR平台接入RTSP设备出现离线情况的排查
    随着科技的飞速进步,视频监控系统已经成为了我们生活和工作中不可或缺的一部分。从最早的模拟监控系统到现在的数字监控系统,视频监控经历了漫长的发展历程。如今,我们生活在一个被视频监控系统包围的时代,无论是城市交通、银行、商场、公共场所等,都离不开视频监控系统的应用。有用户......
  • XmlRPC入门_基于组合类型的客户端、服务端
    1、客户端#include<stdlib.h>#include<stdio.h>#include<xmlrpc-c/base.h>#include<xmlrpc-c/client.h>#include"config.h"/*informationaboutthisbuildenvironment*/#defineNAME"Xmlrpc-cTestClient"#d......
  • 8.4 Windows驱动开发:文件微过滤驱动入门
    MiniFilter微过滤驱动是相对于SFilter传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数IRP操作都由过滤管理器(FilterManager或Fltmgr)所接管,因为有了兼容层,所以在......
  • .net core 使用Task多线程执行任务,限制线程数量,并等待所有任务结束
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespaceDataService.ETL_ApiData{publicclassMultiTask{///<summary>///最大线程数量///</summa......
  • 代码随想训练营第五十二天(Python)| 300.最长递增子序列、674. 最长连续递增序列、718.
    300.最长递增子序列classSolution:deflengthOfLIS(self,nums:List[int])->int:iflen(nums)<=1:returnlen(nums)#dp数组代表以nums[i]结尾的最长递增子序列长度为dp[i]dp=[1]*len(nums)res=1......
  • 畅网全新N100 NAS主板悄悄上架了
     来看看靓照 ......
  • Debian系统使用技巧
    使用过nohup等命令运行程序到后台,发现后面总会无法长时间保留后台,最后只能使用虚拟终端(Screen)来实现后台程序啦#安装虚拟终端aptinstallscreen#查看正在运行的虚拟终端screen-ls#创建虚拟终端忽略是否存在重名的终端⚠不推荐使用,会造成多个重复的虚拟终端不容易......
  • 【xargs】关于 xargs 的使用
    xargs参数使用(1)使用xargs执行指令:有一个info.log文件catinfo.logabc使用一下xargs,这样看起来意义不大catinfo.log|xargsechoabc可以换一个场景,在某个文件夹下,找到指定文件名的文件,然后删除它find./test/|grep-v不能删|xargsrmfind./test......
  • CSS进阶2-弹性布局-弹性盒子
     本节重点:弹性布局(弹性盒子)BFC布局/规范CSS新属性,不包含边框和内边距CSS3的拓展:普通盒模型,怪异盒子模型(IE)  在学习弹性布局前,我们学过Float浮动和Position定位,浮动会出现一些‘诡异’的事情,定位则用起来相对麻烦,弹性布局用起来就会很舒服。1......
  • 二维数点/二维偏序
    二维数点/二维偏序模型:给定二维点集,给定矩阵集,问每个矩阵中有多少个点。此处二维偏序关系的问题也大都如此。这里使用树状数组和二维前缀和容斥拆解思想求解。例题:P2163[SHOI2007]园丁的烦恼代码:#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;......