unity Dictionary序列化和反序列化及XML本地資料儲存
阿新 • • 發佈:2019-02-16
直接上程式碼
首先是XML形式儲存本地資料
XMLManager類
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public class XMLManager{
/// 資料物件轉換xml字串
public static 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;
}
/// xml字串轉換資料物件
public static 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>
/// UTF8位元組陣列轉字串
/// </summary>
/// <param name="characters"></param>
/// <returns></returns>
public static string UTF8ByteArrayToString(byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
string constructedString = encoding.GetString(characters);
return (constructedString);
}
/// <summary>
/// 字串轉UTF8位元組陣列
/// </summary>
/// <param name="pXmlString"></param>
/// <returns></returns>
public static byte[] StringToUTF8ByteArray(System.String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
/// 建立文字檔案
public static void CreateTextFile(string fileName, string strFileData, bool isEncryption)
{
StreamWriter writer; //寫檔案流
string strWriteFileData;
if (isEncryption)
{
strWriteFileData = Encrypt(strFileData); //是否加密處理
}
else
{
strWriteFileData = strFileData; //寫入的檔案資料
}
writer = File.CreateText(fileName);
writer.Write(strWriteFileData);
writer.Close(); //關閉檔案流
}
/// 讀取文字檔案
public static string LoadTextFile(string fileName, bool isEncryption)
{
StreamReader sReader; //讀檔案流
string dataString; //讀出的資料字串
sReader = File.OpenText(fileName);
dataString = sReader.ReadToEnd();
sReader.Close(); //關閉讀檔案流
if (isEncryption)
{
return Decrypt(dataString); //是否解密處理
}
else
{
return dataString;
}
}
/// 加密方法
/// 描述: 加密和解密採用相同的key,具體值自己填,但是必須為32位
public static 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);
}
/// 解密方法
/// 描述: 加密和解密採用相同的key,具體值自己填,但是必須為32位
public static 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>
/// <param name="dataPath"></param>
public static void XmlLocalStorageWrite(object pObject, System.Type ty, string dataPath)
{
//儲存資料
string s = SerializeObject(pObject, ty);
//建立XML檔案且寫入資料
CreateTextFile(dataPath, s, false);
}
}
相比PlayerPrefs,能儲存自定義資料結構的資料
如
public class User
{
private string name;
private string pas;
}
//user[],Link<user>等都可以儲存在本地,但Dictionary<int,user>不行
xml儲存和反序列化獲取方法
public static string dataPathSave = "F:/unityLearning/Assets/Save/";//路徑
public static List<user> userList = new List<user>();
XMLManager.XmlLocalStorageWrite(userList, typeof(List<user>), dataPathSave + "user");//儲存
//反序列化獲取
string strTemp = XMLManager.LoadTextFile(dataPathSave + "user", false);
List<user> List = XMLManager.DeserializeObject(strTemp, typeof(List<user>)) as List<user>;
Dictionary序列化和反序列化
之前提到dictionary不能成功,所有有了下面的方法
DictionaryXML
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml.Serialization;
public class DictionaryXML
{
[Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
#region 建構函式
public SerializableDictionary()
: base()
{
}
public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
: base(dictionary)
{
}
public SerializableDictionary(IEqualityComparer<TKey> comparer)
: base(comparer)
{
}
public SerializableDictionary(int capacity)
: base(capacity)
{
}
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
: base(capacity, comparer)
{
}
protected SerializableDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
#endregion 建構函式
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// 從物件的 XML 表示形式生成該物件
/// </summary>
/// <param name="reader"></param>
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
/**/
/// <summary>
/// 將物件轉換為其 XML 表示形式
/// </summary>
/// <param name="writer"></param>
public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion IXmlSerializable Members
}
}
呼叫
public static DictionaryXML.SerializableDictionary<string, user> Dic = new DictionaryXML.SerializableDictionary<string, user>();//不能是 public static Dictionary<string, user> Dic = new Dictionary<string, user>();
//儲存
using (FileStream fileStream = new FileStream(dataPathSave + "pokraceDic", FileMode.Create))
{
XmlSerializer xmlFormatter = new XmlSerializer(typeof(DictionaryXML.SerializableDictionary<string, user>));
xmlFormatter.Serialize(fileStream,Dic);
}
//反序列化獲取儲存的dictionary
using (FileStream fileStream = new FileStream(dataPathSave + "user", FileMode.Open))
{
XmlSerializer xmlFormatter = new XmlSerializer(typeof(DictionaryXML.SerializableDictionary<string, user>));
Dic = (DictionaryXML.SerializableDictionary<string, user>)xmlFormatter.Deserialize(fileStream);
}