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);
}
}
}
}
}

存储的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文件内容:

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);
}
}
}
}

Unity学习笔记--数据持久化XML文件(2)的更多相关文章

  1. Android(java)学习笔记185:xml文件生成

    1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...

  2. Android(java)学习笔记128:xml文件生成

    1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...

  3. Android学习笔记(9):使用XML文件和Java代码控制UI界面

    Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...

  4. Android学习笔记之AndroidManifest.xml文件解析(转)

    //自已备注: <?xml version="1.0" encoding="utf-8"?>//说明了版本号,字符集 <manifest xm ...

  5. Android学习笔记之AndroidManifest.xml文件解析

    一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...

  6. Android学习笔记之AndroidManifest.xml文件解析(详解)

    一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...

  7. Excel开发学习笔记:读取xml文件及csv文件

    遇到一个数据处理自动化的问题,于是打算开发一个基于excel的小工具.在业余时间一边自学一边实践,抽空把一些知识写下来以备今后参考,因为走的是盲人摸象的野路子,幼稚与错误请多包涵. ).Split(  ...

  8. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

  9. php添加数据到xml文件的例子

    php添加数据到xml文件中 时间:2015-12-17 06:30:37来源:网络 导读:php添加数据到xml文件中   xml文件:stu.xml: 复制代码代码如下: <?xml ver ...

  10. Java NIO 学习笔记(四)----文件通道和网络通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

随机推荐

  1. 如何做一个完美的api接口?

    如何做一个api接口?:我们知道API其实就是应用程序编程接口,可以把它理解为是一种通道,用来和不同软件系统间进行通信,本质上它是预先定义的函数:-api,接口 1 我们知道API其实就是应用程序编程 ...

  2. 使用 OpenTelemetry 构建 .NET 应用可观测性(2):OpenTelemetry 项目简介

    前世今生 OpenTracing OpenTracing 项目启动于 2016 年,旨在提供一套分布式追踪标准,以便开发人员可以更轻松地实现分布式追踪. OpenTracing 定义了一套 Traci ...

  3. JNI动态注册以及JNI签名

    一.动态注册和静态注册 注册native方法有两种方式,动态注册和静态注册.静态注册是在编译时进行注册,而且在java中声明的native方法和c/c++中的本地方法的对应关系是恒定的:比如说在com ...

  4. DAY005_异或运算

    运算规则 二进制:相同为0 相异为1 十进制:相同为0 任何数字和0异或都是它本身 不利用额外变量交换两个数 数组中一种数字出现了奇数次,其他数都出现了偶数次,怎么得到这个出现了奇数次的数 将所有的数 ...

  5. http、socket以及websocket的区别(websocket使用举例)

    一.http.socket.websocket介绍 1.HTTP(Hypertext Transfer Protocol):HTTP是一种应用层协议,用于在客户端和服务器之间传输超文本数据.它是基于请 ...

  6. 7-MySQL函数

    1.分组group by 在MySQL中,GROUP BY的意思是"分组查询",它可以根据一个或多个字段对查询结果进行分组. GROUP BY的作用是通过一定的规则将一个数据集划分 ...

  7. 最快速搭建个人服务器图床siuuuuu

    @ 目录 1.服务器准备 2.docker 安装 (1)通过命令行的方式 (2)宝塔面板上安装 3.开启端口访问 什么是docker 4.docker安装minio 什么是minio 5.配置mini ...

  8. TrueUpdate白加黑木马分析保姆级教程

    目录 TrueUpdate白加黑木马分析保姆级教程 0x00:前言 TrueUpdate是什么? 0x01: TrueUpdate逆向分析解压密码 查壳 脱壳 分金定穴 找到解压密码方法1: 找到解压 ...

  9. 内网离线安装docker并配置使用nexus为docker私服

    背景 本文简单记录下最近在内网服务器离线安装docker及配置nexus作为docker私服,踩的一些坑.docker和k8s这块技术我跟得不是很紧,18年的时候用过一阵docker,后来发现它并不能 ...

  10. c语言代码练习4(改进)

    #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <wi ...