序列化操作
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class BinarySerializer
{
#region Serialize
public static void SerializeToFile<T>(T obj, string fileDir, string fullName)
{
if(!(Directory.Exists(fileDir)))
{
Directory.CreateDirectory(fileDir);
}
string fullPath = string.Format(@"{0}\{1}", fileDir, fullName);
using(FileStream fs = new FileStream(fullPath, FileMode.OpenOrCreate))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, obj);
fs.Flush();
}
}
public static string SerializeToString<T>(T obj)
{
using(MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
return System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
}
#endregion
#region Deserialize
public static T DeserializeFromFile<T>(string path) where T : class
{
using(FileStream fs = new FileStream(path, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
return bf.Deserialize(fs) as T;
}
}
public static T DeserializeFromString<T>(string content) where T : class
{
byte[] arrBytes = System.Text.Encoding.UTF8.GetBytes(content);
using(MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
return bf.Deserialize(ms) as T;
}
}
#endregion
}
序列化对象声明
对类使用序列化时,标注那些不需要序列化的字段。 序列化只能针对字段使用。
[Serializable]
public class MyClass
{
[Noserialized]
public string Temp;
[field:Noserialized] 用于标识event不被序列
public event EventHandler TempChanged;
}
使用序列化相关特性
同时还可以利用特性,在序列化,反序列化执行过程中,自动调用指定的方法,进一步处理序列化数据。例如,可以在执行完反序列化后,自动初始化一些字段。
提供的特性有:
* OnDeserializedAttribute
* OnDeserializingAttribute
* OnSerializedAttribute
* OnSerializingAttribute
using System;
using System.Runtime.Serialization;
[Serializable]
public class SerializableObject
{
[OnSerializingAttribute]
virtual protected void OnSerializing(StreamingContext context)
{
}
[OnSerializedAttribute]
virtual protected void OnSerialized(StreamingContext context)
{
}
[OnDeserializingAttribute]
virtual protected void OnDeserializing(StreamingContext context)
{
}
[OnDeserializedAttribute]
virtual protected void OnDeserialized(StreamingContext context)
{
}
}
深度定制化ISerializable
如果序列化特性不能满足需求,那就需要使用此接口来自定义化序列化操作。甚至可以序列化为另一个对象。
继承了此接口后,序列化特性就不会生效了。
Person p1 = new Person(){FirstName = "Nick", LastName = "Wang"};
BinarySerializer.SerializeToFile(p1, Application.dataPath, "person.txt");
Person p2 = BinarySerializer.DeserializeFromFile<Person>(System.IO.Path.Combine(Application.dataPath, "person.txt"));
Debug.Log(p2.FirstName);
[Serializable]
public class Person : ISerializable
{
public string FirstName;
public string LastName;
public string ChineseName;
public Person()
{
}
protected Person(SerializationInfo info, StreamingContext context)
{
FirstName = info.GetString("FirstName");
LastName = info.GetString("LastName");
ChineseName = string.Format("{0} {1}", LastName, FirstName);
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("FirstName", FirstName);
info.AddValue("LastName", LastName);
}
}
序列化为另一个对象
Person p1 = new Person(){FirstName = "Nick", LastName = "Wang"};
BinarySerializer.SerializeToFile(p1, Application.dataPath, "person.txt");
PersonAnother p2 = BinarySerializer.DeserializeFromFile<PersonAnother>(System.IO.Path.Combine(Application.dataPath, "person.txt"));
Debug.Log(p2.Name);
[Serializable] public class PersonAnother : ISerializable { public string Name; public PersonAnother() { } protected PersonAnother(SerializationInfo info, StreamingContext context) { Name = info.GetString("Name"); } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { } } [Serializable] public class Person : ISerializable { public string FirstName; public string LastName; public string ChineseName; public Person() { } protected Person(SerializationInfo info, StreamingContext context) { } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { info.SetType(typeof(PersonAnother));} info.AddValue("Name", string.Format("{0} {1}", LastName, FirstName)); } }