XML檔案的序列化和反序列化
阿新 • • 發佈:2018-11-07
一、編寫資料實體類,如下所示:
/*** * * Title: * 資料持久化技術 * * Description: * 功能: * XML讀寫 * 關卡資料物件 * * Date: 2018 * * Version: 1.0 * * Modify Recorder: * */ using UnityEngine; using System.Collections; public class LevelData{ public int LevelNumber; //關卡編號 public bool IsUnlock; //關卡是否解鎖 public string LevelName; //關卡名稱 public LevelDetailInfo LevelDetailInfos; //關卡詳情要求 public LevelData(){} public LevelData(int levelNumber, bool isUnlock, string levelname,LevelDetailInfo detailInfo){ this.LevelNumber = levelNumber; this.IsUnlock = isUnlock; this.LevelName = levelname; this.LevelDetailInfos = detailInfo; } }
/*** * * Title: * 資料持久化技術 * * Description: * 功能: * XML讀寫 * 資料物件內嵌物件: 關卡詳細資訊 * * Date: 2017 * * Version: 1.0 * * Modify Recorder: * */ using UnityEngine; using System.Collections; public class LevelDetailInfo{ public string DemandOfPass; //通關要求 public string DetailContent; //詳細內容 public LevelDetailInfo() { } public LevelDetailInfo(string demandOfPass, string content){ this.DemandOfPass = demandOfPass; this.DetailContent = content; } }
二、編寫XML的核心讀/寫操作類(包含序列化、反序列化、加密)
/*** * * Title: * 資料持久化技術 * * Description: * 功能: * XML讀寫 * XML 讀寫核心類 * * Date: 2017 * * Version: 1.0 * * Modify Recorder: * */ using System.Collections; using System.Xml; using System.Xml.Serialization; using System.IO; using System.Text; using System.Security.Cryptography; using System; public class XmlOperation{ private static XmlOperation _Instance = null; //靜態類物件 public static XmlOperation GetInstance() { if (_Instance == null) { _Instance = new XmlOperation(); } return _Instance; } /// <summary> 加密方法 /// 加密方法 /// /// 描述: 加密和解密採用相同的key,具體值自己填,但是必須為32位 /// </summary> /// <param name="toE"></param> /// <returns></returns> public string Encrypt(string toE){ byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012"); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toE); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length); return Convert.ToBase64String(resultArray,0,resultArray.Length); } /// <summary> 解密方法 /// 解密方法 /// /// 描述: 加密和解密採用相同的key,具體值自己填,但是必須為32位 /// </summary> /// <param name="toD"></param> /// <returns></returns> public string Decrypt(string toD){ byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012"); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; rDel.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] toEncryptArray = Convert.FromBase64String(toD); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } /// <summary> 序列化物件 /// 序列化物件 /// </summary> /// <param name="pObject">進行序列化的物件</param> /// <param name="ty">序列化物件的型別</param> /// <returns></returns> public string SerializeObject(object pObject,System.Type ty){ string XmlizedString = null; MemoryStream memoryStream = new MemoryStream(); XmlSerializer xs = new XmlSerializer(ty); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); xs.Serialize(xmlTextWriter, pObject); memoryStream = (MemoryStream)xmlTextWriter.BaseStream; XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray()); return XmlizedString; } /// <summary> 反序列化物件 /// 反序列化物件 /// </summary> /// <param name="pXmlizedString"></param> /// <param name="ty"></param> /// <returns></returns> public object DeserializeObject(string pXmlizedString , System.Type ty){ XmlSerializer xs = new XmlSerializer(ty); MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString)); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); return xs.Deserialize(memoryStream); } /// <summary> 建立XML檔案 /// 建立XML檔案 /// </summary> /// <param name="fileName">檔名稱</param> /// <param name="strFileData">寫入的檔案資料</param> public void CreateXML(string fileName,string strFileData){ StreamWriter writer; //寫檔案流 //string strWriteFileData = Encrypt(strFileData); //是否加密處理 string strWriteFileData = strFileData; //寫入的檔案資料 writer = File.CreateText(fileName); writer.Write(strWriteFileData); writer.Close(); //關閉檔案流 } /// <summary> 讀取XML檔案 /// 讀取XML檔案 /// </summary> /// <param name="fileName">檔名稱</param> /// <returns></returns> public string LoadXML(string fileName){ StreamReader sReader; //讀檔案流 string dataString; //讀出的資料字串 sReader = File.OpenText(fileName); dataString = sReader.ReadToEnd(); sReader.Close(); //關閉讀檔案流 //return Decrypt(dataString); //是否解密處理 return dataString; } //判斷是否存在檔案 public bool hasFile(String fileName){ return File.Exists(fileName); } //UTF8位元組陣列轉字串 public string UTF8ByteArrayToString(byte[] characters ){ UTF8Encoding encoding = new UTF8Encoding(); string constructedString = encoding.GetString(characters); return (constructedString); } //字串轉UTF8位元組陣列 public byte[] StringToUTF8ByteArray(String pXmlString ){ UTF8Encoding encoding = new UTF8Encoding(); byte[] byteArray = encoding.GetBytes(pXmlString); return byteArray; } }
三、XML測試類
/***
*
* Title:
* 資料持久化技術
*
* Description:
* 功能:
* XML讀寫
* XML讀寫測試主指令碼
*
* Date: 2017
*
* Version: 1.0
*
* Modify Recorder:
*
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TestXML : MonoBehaviour {
//關卡資料集合
public List<LevelData> listLevelData = new List<LevelData>(); //關卡資料集合
//資料持久化路徑
static string _fileName;
void Start () {
_fileName = Application.persistentDataPath + "/UnityProjectLevelData";
//建立測試用例
TestCase();
//儲存物件到XML
StoreDateToXMLFile();
//讀取測試
ReadDateFromXMLFile();
}
/// <summary>
/// 定義初始化測試用例資料
/// </summary>
public void TestCase(){
LevelDetailInfo levelDetailInfo0=new
LevelDetailInfo("消除2課紅鑽石", "需要同時消除2課以上的紅色鑽石,時間5分鐘內完成");
LevelDetailInfo levelDetailInfo1 = new
LevelDetailInfo("消除5課紅鑽石", "需要同時消除5課以上的紅色鑽石,時間2分鐘內完成");
listLevelData.Add(new LevelData(0, true, "第一關", levelDetailInfo0));
listLevelData.Add(new LevelData(1, true, "第二關", levelDetailInfo1));
}
/// <summary>
/// 儲存資料到XML檔案
/// </summary>
public void StoreDateToXMLFile()
{
//物件序列化
string s = XmlOperation.GetInstance().SerializeObject(listLevelData, typeof(List<LevelData>));
print("持久化xml 資料 s=" + s);
print("建立XML檔案_fileName=" + _fileName);
//建立XML檔案且寫入資料
XmlOperation.GetInstance().CreateXML(_fileName, s);
print("建立XML完成");
}
/// <summary>
/// 從XML檔案中讀取資料
/// </summary>
public void ReadDateFromXMLFile(){
try{
//讀取資料
string strTemp = XmlOperation.GetInstance().LoadXML(_fileName);
print("讀取的原始XML資料字串: " + strTemp);
//反序列化物件
listLevelData = XmlOperation.GetInstance().DeserializeObject
(strTemp, typeof(List<LevelData>)) as List<LevelData>;
//讀取出來
foreach (LevelData dataItem in listLevelData){
print("");
print("關卡序號: " + dataItem.LevelNumber);
print("關卡名稱: " + dataItem.LevelName);
print("關卡鎖定: " + dataItem.IsUnlock);
print("過關要求: " + dataItem.LevelDetailInfos.DemandOfPass);
print("詳細說明: " + dataItem.LevelDetailInfos.DetailContent);
}
}
catch{
print("系統讀取XML出現錯誤,請檢查");
}
}
}
注:本示例來自《Unity3D/2D遊戲開發從0到1》第26章資料持久化內容。