这段时间在研究和学习C#的序列化和反序列化的东西。发现这是一个非常友好的数据本地store的方式。但是在使用过程中也有很多有意思的地方,我这里把我越到的问题列一下。我使用的是C#的二进制形式的序列化和反序列化。
参考了这里,还有这里。这两个参考地方都有对于的code。从code中可以得到的结果是:在serialize之前,都是将需要序列化的数据放到一个结构体里面去,然后开始序列化。对于这个被序列化的结构体的要求就是她已经实现了ISerializable的GetObjectData方法,还有一个参数为SerializationInfo info, StreamingContext context的构造函数。在这个构造函数中将从info中得到的信息赋值给这个数据结构的属性变量。而在GetObjectData方法中有着与以上说的构造函数一直的参数,在这个函数中是将数据结构的属性变量的指添加到info中去。如:
[Serializable] public class MyObject : ISerializable { public int n1; public int n2; public String str; public MyObject() { } protected MyObject(SerializationInfo info, StreamingContext context) { n1 = info.GetInt32("i"); n2 = info.GetInt32("j"); str = info.GetString("k"); } public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("i", n1); info.AddValue("j", n2); info.AddValue("k", str); } }
回到开始之处,如何开始序列化。看code:
using System; using System.IO; using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; public class App { [STAThread] static void Main() { Serialize(); Deserialize(); } static void Serialize() { // Create a hashtable of values that will eventually be serialized. Hashtable addresses = new Hashtable(); addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052"); addresses.Add("Fred", "987 Pine Road, Phila., PA 19116"); addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301"); // To serialize the hashtable and its key/value pairs, // you must first open a stream for writing. // In this case, use a file stream. FileStream fs = new FileStream("DataFile.dat", FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); try { formatter.Serialize(fs, addresses); } catch (SerializationException e) { Debug.Log("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } static void Deserialize() { // Declare the hashtable reference. Hashtable addresses = null; // Open the file containing the data that you want to deserialize. FileStream fs = new FileStream("DataFile.dat", FileMode.Open); try { BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the hashtable from the file and // assign the reference to the local variable. addresses = (Hashtable) formatter.Deserialize(fs); } catch (SerializationException e) { Debug.Log("Failed to deserialize. Reason: " + e.Message); throw; } finally { fs.Close(); } // To prove that the table deserialized correctly, // display the key/value pairs. foreach (DictionaryEntry de in addresses) { Debug.Log( de.Key+ de.Value); } } }
需要注意的是,什么的做法在mac上是ok的。但是,如果发布到ios上面的话,可能就出错了哦。上面使用的是hashtable,如果她的key或value是自定义的一种类型的话,在ios中可能就,filename unknown 0 等等的。。。我在网上找到的方式是不使用自定义的类型,而是将自定义的数据里面的数据字段重新组合成基本数据类型再作为value后进行序列化。比如: 一个自定义数据类型由三种自定义类型构成,int m_n ,bool m_b,string m_str。我将按照这样的方式来组合成一个新的string, string value = new StringBuilder().Append(m_n).Append(“#”).Append(m_b).Append(“#”).Append(m_str).ToString();这样就得到了一个key对应的value。在反序列化的时候,使用split函数可以将这个string再拆开成int,bool,string类型。这样数据就还原了。如此之后也可以解决在ios上面的filename unknown 0的问题。