参考:刘国柱大神书籍:Unity3D/2D游戏开发,26章-数据持久化技术
XMLOperation代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; // XmlSerializer引入命名空间 using System.Xml.Serialization; // Convert,Type引入命名空间 using System; // MemoryStream引入命名空间 using System.IO; // XmlTextWriter引入命名空间 using System.Xml; // RijndaelManaged引入命名空间 using System.Security.Cryptography; // UTF8引入命名空间 using System.Text; public class XMLOperation { private static XMLOperation instance = null; public static XMLOperation Instance { get { if (instance == null) { instance = new XMLOperation (); } return instance; } } /// <summary> /// 加密方法 /// </summary> /// <param name="toE">To e.</param> public string Encrypt (string toE) { //加密和解密必须采用相同的key,具体自己填写,但是必须为32位 byte[] keyArray = UTF8Encoding.UTF8.GetBytes ("12345678123456781234567812345678"); //访问 Rijndael 算法的托管版本 RijndaelManaged rDel = new RijndaelManaged (); //设置对称算法的密钥 模式 填充模式 rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; //用当前的 Key 属性和初始化向量 (IV) 创建对称加密器对象。 ICryptoTransform cTrans = rDel.CreateEncryptor (); //转换为UTF8编码的字节数组 byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toE); byte[] resultArray = cTrans.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length); //将8位元不带正负号的整数阵列的值,转换为使用Base-64 位数编码的相等字串表示。 return Convert.ToBase64String (resultArray, 0, resultArray.Length); } /// <summary> /// 解密方法 /// </summary> /// <param name="toD">To d.</param> public string Decrypt (string toD) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes ("12345678123456781234567812345678"); RijndaelManaged rDel = new RijndaelManaged (); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTrans = rDel.CreateDecryptor (); byte[] toEncryptArray = Convert.FromBase64String (toD); byte[] resultArray = cTrans.TransformFinalBlock (toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString (resultArray); } /// <summary> /// 序列化对象 /// </summary> /// <returns>The object.</returns> /// <param name="pObjcet">P objcet.</param> /// <param name="type">Type.</param> public string SerializeObject (object pObjcet, Type type) { string XMLizedString = null; //系统内存提供流式的读写操作,常作为其他流数据交换时的中间对象操作。 MemoryStream memoryStream = new MemoryStream (); //XMLSerializer 对象使你能够把一个 XML 文档或 Node 对象转化或“序列化”为未解析的 XML 标记的一个字符串 XmlSerializer xs = new XmlSerializer (type); // XmlTextWriter 写文件 XmlTextWriter xmlTextWriter = new XmlTextWriter (memoryStream, Encoding.UTF8); //序列化对象 xs.Serialize (xmlTextWriter, pObjcet); memoryStream = (MemoryStream)xmlTextWriter.BaseStream; XMLizedString = UTF8ByteArrayToString (memoryStream.ToArray ()); return XMLizedString; } /// <summary> /// 反序列化对象 /// </summary> /// <returns>The serialize object.</returns> /// <param name="XmlizedString">Xmlized string.</param> /// <param name="type">Type.</param> public object DeSerializeObject (string XmlizedString, Type type) { //XMLSerializer 对象使你能够把一个 XML 文档或 Node 对象转化或“序列化”为未解析的 XML 标记的一个字符串 XmlSerializer xs = new XmlSerializer (type); MemoryStream memoryStream = new MemoryStream (StringToUTF8ByteArray (XmlizedString)); XmlTextWriter xmlTextWriter = new XmlTextWriter (memoryStream, Encoding.UTF8); return xs.Deserialize (memoryStream); } /// <summary> /// 创建XML文件 /// </summary> /// <param name="fileName">文件名.</param> /// <param name="fileDate">文件数据.</param> public void CreateXML (string fileName, string fileData) { //写文件流 StreamWriter sWrite; //是否加密处理 //string strWriteFileData = Encrypt (fileData); //写入文件数据 string strWriteFileData = fileData; //创建文件 sWrite = File.CreateText (fileName); //文件写入数据 sWrite.Write (strWriteFileData); //关闭文件流 sWrite.Close (); } /// <summary> /// 读取文件 /// </summary> /// <returns>The XM.</returns> /// <param name="fileName">文件名</param> public string LoadXML (string fileName) { //读文件流 StreamReader sReader; //读取数据字符串 string dataStr; sReader = File.OpenText (fileName); dataStr = sReader.ReadToEnd (); //关闭文件流读取 sReader.Close (); //是否加密处理 //return Decrypt (dataStr); return dataStr; } /// <summary> /// 判断是否存在文件 /// </summary> /// <returns><c>true</c> if this instance has file the specified fileName; otherwise, <c>false</c>.</returns> /// <param name="fileName">File name.</param> public bool HasFile (String fileName) { return File.Exists (fileName); } /// <summary> /// UTF8字节数组转字符串 /// </summary> /// <returns>The f8 byte array to string.</returns> /// <param name="characters">Characters.</param> public string UTF8ByteArrayToString (byte[] characters) { UTF8Encoding encoding = new UTF8Encoding (); string constructString = encoding.GetString (characters); return constructString; } /// <summary> /// 字符串转UTF8字节数组 /// </summary> /// <returns>The to UT f8 byte array.</returns> /// <param name="xmlString">Xml string.</param> public byte[] StringToUTF8ByteArray (String xmlString) { UTF8Encoding encoding = new UTF8Encoding (); byte[] byteArray = encoding.GetBytes (xmlString); return byteArray; } }
LevelData代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LevelData { /// <summary> /// 关卡编号 /// </summary> public int levelNumber; /// <summary> /// 关卡是否解锁 /// </summary> public bool isUnlock; /// <summary> /// 关卡名字 /// </summary> public string levelName; /// <summary> /// 关卡详情 /// </summary> public LevelDetailInfo levelDetailInfos; public LevelData () { } public LevelData (int levelNumber, bool isUnlock, string levelName, LevelDetailInfo levelDetailInfos) { this.levelNumber = levelNumber; this.isUnlock = isUnlock; this.levelName = levelName; this.levelDetailInfos = levelDetailInfos; } }
LevelDetailInfo代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LevelDetailInfo { /// <summary> /// 通关要求 /// </summary> public string DemandOfPass; /// <summary> /// 详细内容 /// </summary> public string DetailContent; public LevelDetailInfo () { } public LevelDetailInfo (string DemandOfPass, string DetailContent) { this.DemandOfPass = DemandOfPass; this.DetailContent = DetailContent; } }
TestXML代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestXML : MonoBehaviour { //关卡数据集合 public List<LevelData> levelDateList = new List<LevelData> (); static string fileName; void Start () { fileName = Application.persistentDataPath + "/UnityLevelData"; TestCase (); StoreDataToXMLFile (); ReadDataFromXMLFile (); } /// <summary> /// xml描述 /// </summary> void TestCase () { LevelDetailInfo levelDetailInfo0 = new LevelDetailInfo ("我是第一关的描述要求", "我是第一关的详细内容,跑酷"); LevelDetailInfo levelDetailInfo1 = new LevelDetailInfo ("我是第二关的描述要求", "我是第二关的详细内容,穿针"); levelDateList.Add (new LevelData (0, true, "第一关", levelDetailInfo0)); levelDateList.Add (new LevelData (1, true, "第二关", levelDetailInfo1)); } /// <summary> /// 写入数据 /// </summary> void StoreDataToXMLFile () { string s = XMLOperation.Instance.SerializeObject (levelDateList, typeof(List<LevelData>)); Debug.Log ("持久化xml = " + s); Debug.Log ("创建文件名fileName的路径 = " + fileName); XMLOperation.Instance.CreateXML (fileName, s); string encrypt = XMLOperation.Instance.Encrypt (s); Debug.Log ("加密的 = " + encrypt); string decrypt = XMLOperation.Instance.Decrypt (encrypt); Debug.Log ("解密的 = " + decrypt); } /// <summary> /// 从文件中读取数据 /// </summary> void ReadDataFromXMLFile () { try { string strTemp = XMLOperation.Instance.LoadXML (fileName); levelDateList = XMLOperation.Instance.DeSerializeObject (strTemp, typeof(List<LevelData>))as List<LevelData>; foreach (LevelData item in levelDateList) { Debug.Log ("关卡号 : " + item.levelNumber); Debug.Log ("关卡是否解锁 : " + item.isUnlock); Debug.Log ("关卡名字 : " + item.levelName); Debug.Log ("通关要求 : " + item.levelDetailInfos.DemandOfPass); Debug.Log ("详细内容 : " + item.levelDetailInfos.DetailContent); } } catch (System.Exception ex) { Debug.Log ("读取XML错误 异常" + ex); } } }
打印信息如下: