关闭

[笔记]序列化与反序列化的讨论(二)

378人阅读 评论(0) 收藏 举报

上一篇中,讨论了序列化和反序列化的基础,同时简单说明了如何进行单个类的序列化和反序列化。

一般说来,使用默认的BinaryFormatter已经可得到很高效的字节流了。但是,实际应用中,由于部分数据可能无法被默认的模式自动序列化,自定义序列化就成为必不可少的一部分。自定义序列化的在进行XML序列化的时候尤其重要。因为XML序列化用的是浅序列化模式,也就是说,只有标记为public的公共属性会被序列化,而private的部分则不会被序列化到。通过自定义序列化,我们可以让XML序列化的时候,同时包含我们重建实例所需要的所有参数。dotNET是通过提供了ISerializable接口来达到实现自定义序列化的目的的。

namespace SimulationEnv
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            BinaryFormatter formatter 
= new BinaryFormatter();
            Stream s 
= new MemoryStream();

            Player p 
= new Player("李逍遥");

            
// 序列化
            formatter.Serialize(s, p);

            
byte[] sav = ((MemoryStream)s).ToArray();
            Output(sav);
            Console.Write(
" ");
            Console.ReadLine();

            
// 反序列化
            s.Position = 0;
            Player psav 
= (Player)formatter.Deserialize(s);
            Console.WriteLine(psav.Name);
            Console.ReadLine();
        }


        
private static void Output(byte[] data)
        
{
            
for (int i = 0; i < data.Length; i++)
            
{
                
string str = data[i].ToString("X");
                
if (str.Length == 1)
                
{
                    str 
= "0" + str;
                }

                Console.Write(str 
+ " ");
                
if ((i + 1% 16 == 0)
                
{
                    Console.Write(
" ");
                }

            }

        }
    
    }


    [Serializable]
    
public class Player : ISerializable
    
{
        
public string Name;

        
public Player(string Name)
        
{
            
this.Name = Name;
        }


        
ISerializable Members
    }


}

这里,构造函数Player(SerializationInfo info, StreamingContext context)被用来在反序列化时构造出和原实例完全一样的实例。由于这个构造函数的特殊性,为了防止别的程序有意无意的调用,该构造函数可以声明为private或者protected而不会影响系统本身对它的调用。也就是说,如果是一个已经封装的类,应该声明为private,未封装的类,应该声明为protected,来避免可能造成的系统安全隐患。

有趣的是,根据自定义序列化,我们可以序列化一个类以后,在反序列化的时候,将其反序列化为另外一个类。

namespace SimulationEnv
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            BinaryFormatter formatter 
= new BinaryFormatter();
            Stream s 
= new MemoryStream();

            Player p 
= new Player("李逍遥");

            
// 序列化
            formatter.Serialize(s, p);

            
byte[] sav = ((MemoryStream)s).ToArray();
            Output(sav);
            Console.Write(
" ");
            Console.ReadLine();

            
// 反序列化
            s.Position = 0;
            TeamPlayer tp 
= (TeamPlayer)formatter.Deserialize(s);
            Console.WriteLine(tp.Name);
            Console.ReadLine();
        }


        
private static void Output(byte[] data)
        
{
            
for (int i = 0; i < data.Length; i++)
            
{
                
string str = data[i].ToString("X");
                
if (str.Length == 1)
                
{
                    str 
= "0" + str;
                }

                Console.Write(str 
+ " ");
                
if ((i + 1% 16 == 0)
                
{
                    Console.Write(
" ");
                }

            }

        }
    
    }


    [Serializable]
    
public class Player : ISerializable
    
{
        
public string Name;

        
public Player(string Name)
        
{
            
this.Name = Name;
        }


        
ISerializable Members
    }


    [Serializable]
    
public class TeamPlayer
    
{
        
public string Name;
    }

}

通过info.SetType(),可以自定义在反序列化的时候,将其反序列化为某个特定的类。这点特性在某些时候很有用。比如,在进行系统整合的时候,服务端有一个类Product,且这个类是已经包装好的,不可以更改。但是客户端只能够发送Service的类。这时候,就可以用自定义的序列化,在序列化的时候,将Service类直接映射为Product类。这样,服务端进行反序列化的时候,得到的是Product类而不是Service。当然,这也需要服务端是使用反序列化来获得Product类的情况才可以。

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10139次
    • 积分:168
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    文章存档