我們主要是使用Marshal類里的兩個(gè)方法:
第一個(gè)是StructureToPtr,,將數(shù)據(jù)從托管對象封送到非托管內(nèi)存塊,。
第二個(gè)是PtrToStructure,將數(shù)據(jù)從非托管內(nèi)存塊封送到新分配的指定類型的托管對象,。
只要有了這兩個(gè)相互轉(zhuǎn)換的方法,,我們就可以實(shí)現(xiàn)序列化了。
首先我們先來看下序列化
序列化: 有一個(gè)前提條件,,那就是我們必須要知道需要序列化對象的大小,。
第一步:我們先求出對象的大小,然后在非托管內(nèi)存中給它分配相應(yīng)的內(nèi)存大小,。
第二步:接著我們就把這個(gè)對象封送到剛分配出來的內(nèi)存中,,之后我們會得到一個(gè)分配出來的內(nèi)存塊首地址指針。
第三步:最后我們可以通過這個(gè)首地址指針,,從指針?biāo)傅奈恢锰庨_始,,拷貝數(shù)據(jù)到指定的byte[]數(shù)組中,拷貝的長度就是我們?yōu)檫@個(gè)對象分配出來的內(nèi)存大小,,得到byte[]數(shù)據(jù)后,,下面的事情我就不用多說了,你可以保存到數(shù)據(jù)庫或者文件中,。
反序列化: 序列化的時(shí)候我們先將一個(gè)對象封送到了非托管內(nèi)存塊中,,然后再把內(nèi)存塊中的數(shù)據(jù)讀到byte[]數(shù)組中,
現(xiàn)在我們反序列化
第一步:我們先求出對象的大小,,然后在非托管內(nèi)存中給它分配相應(yīng)的內(nèi)存大小,。
第二步:然后把這個(gè)byte[]數(shù)據(jù)拷貝到非托管內(nèi)存塊中。
第三步:最后再從內(nèi)存塊中封送指定大小的數(shù)據(jù)到對象中,。
有一個(gè)地方需要注意,,那就是因?yàn)橐妙愋偷膶ο笪覀兪菬o法求的它的實(shí)際大小的,所以這里的對象我們只能使用非托管對象,比如struct結(jié)構(gòu)體,。
所以,,當(dāng)我們只是用來存儲數(shù)據(jù),不涉及任何操作的對象,,我們可以把它作為一個(gè)結(jié)構(gòu)體來處理,,這樣我們在序列化的時(shí)候可以節(jié)省空間開銷。
因?yàn)槟闳绻阋怯闷匠5男蛄谢椒ㄈバ蛄谢粋€(gè)類對象,,他所需要的空間開銷是要大于你去序列化一個(gè)具有相同結(jié)構(gòu)的struct對象,。
下面是代碼:
public static class MyConverter { /// <summary> /// 由結(jié)構(gòu)體轉(zhuǎn)換為byte數(shù)組 /// </summary> public static byte[] StructureToByte<T>(T structure) { int size = Marshal.SizeOf(typeof(T)); byte[] buffer = new byte[size]; IntPtr bufferIntPtr = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(structure, bufferIntPtr, true); Marshal.Copy(bufferIntPtr, buffer, 0, size); } finally { Marshal.FreeHGlobal(bufferIntPtr); } return buffer; }
/// <summary> /// 由byte數(shù)組轉(zhuǎn)換為結(jié)構(gòu)體 /// </summary> public static T ByteToStructure<T>(byte[] dataBuffer) { object structure = null; int size = Marshal.SizeOf(typeof(T)); IntPtr allocIntPtr = Marshal.AllocHGlobal(size); try { Marshal.Copy(dataBuffer, 0, allocIntPtr, size); structure = Marshal.PtrToStructure(allocIntPtr, typeof(T)); } finally { Marshal.FreeHGlobal(allocIntPtr); } return (T)structure; } }
//////////////////////////////////測試代碼/////////////////////////////////// class Program { static void Main(string[] args) { Student student1 = new Student { Name = "胡昌俊", ID = 2 }; Console.WriteLine("序列化前=> 姓名:{0} ID:{1}", student1.ID, student1.Name);
byte[] bytes = MyConverter.StructureToByte<Student>(student1); Student sudent2 = MyConverter.ByteToStructure<Student>(bytes);
Console.WriteLine("序列化后=> 姓名:{0} ID:{1}", sudent2.ID, sudent2.Name); Console.Read(); } }
public struct Student { public int ID { get; set; } public string Name { get; set; } }
|