xingd.net

.net related techonology

导航

BinaryFormatter序列化实例(一)

Posted on 2005-01-29 21:29  xingd  阅读(3305)  评论(3编辑  收藏  举报

  前几天写了一篇.NET序列化概述性的文章,有朋友说对技术的描述不够详细,因此准备写一系列文章,以一个实例为基础,详细描述各种序列化的使用方法和注意事项。这一系列文章是为不熟悉序列化的读者准备的,已用过序列化的可以只看一下每篇中加粗的一句话,感兴趣再阅读全文。文中的示例类Voucher和VoucherItem非常简化,实际中的凭证包含更多的信息。
  财务系统中经常要与凭证打交道,在这篇文章里,我们要实现一个Voucher类,它包含凭证和业务信息,并且能够保存为磁盘文件,以便于没有专用网络的分布式企业中,可以在终端输入凭证,然后通过拨号的方式将凭证批量更新到中心业务系统中。
  凭证中除了包含凭证号,制单人,制单时间等外,还包含多条项目。假设凭证项目也由其他人完成,以Assembly的方式提供,类名为VoucherItem,其定义如下:

public class VoucherItem
{
    
public VoucherItem() {}

    
public string AccountId {get;set;}
    
public decimal DebitAmount {get;set;}
    
public decimal CreaditAmount {get;set;}
}

  首先,我们要实现Voucher的主体类及其序列化,然后再把VoucherItem加到Voucher类上。
public class Voucher
{
    
private string voucherId;
    
private string creator;
    
private DateTime createTime;
    
private string description;
    
    
public Voucher(string voucherId, string creator, DateTime createTime)
    
{
        
this.voucherId = voucherId;
        
this.creator = creator;
        
this.createTime = createTime;
    }


    
public string VoucherId
    
{
        
get
        
{
            
return voucherId;
        }

    }


    
public string Creator
    
{
        
get
        
{
            
return creator;
        }

    }


    
public DateTime CreateTime
    
{
        
get
        
{
            
return createTime;
        }

    }


    
public string Description
    
{
        
get
        
{
            
return description;
        }

        
set
        
{
            description 
= value;
        }

    }

}


  为了将Voucher保存到磁盘,考虑最直接的方法是序列化,而为了通过拨号传到业务中心的需要,应当保存较小的磁盘文件,所以使用二进制序列化。
序列化代码如下:
public class VoucherSerializer
{
    
public VoucherSerializer()
    
{
        
    }


    
public void Serialize(string filename, Voucher voucher)
    
{
        BinaryFormatter formatter 
= new BinaryFormatter();
        FileStream fs 
= new FileStream(filename, FileMode.Create);
        formatter.Serialize(fs, voucher);
        fs.Close();
    }

}

  从上面的代码可以看出,借助.NET Framework的帮助,实现类的二进制序列化是非常容易的。序列化方法写好后,马上用NUnit做一个测试类。

[TestFixture]
public class VoucherTest
{
    
public VoucherTest()
    
{

    }


    [Test]
    
public void TestSerializeVoucher()
    
{
        Voucher voucher 
= new Voucher("2005012900001""xingd", DateTime.Now);

        VoucherSerializer serializer 
= new VoucherSerializer();
        serializer.Serialize(
"voucher.dat", voucher);
    }

}


  兴冲冲地打开NUnit GUI,选中Assembly,运行测试。
  啊,怎么会有错误呢,这么简单的类。
GeneralLedger.VoucherTest.TestSerializeVoucher : System.Runtime.Serialization.SerializationException : The type GeneralLedger.Voucher in Assembly Voucher, Version=1.0.1855.38026, Culture=neutral, PublicKeyToken=null is not marked as serializable.

  原来是这个错。能够进行二进制序列化的类必须在类定义中添加SerializableAttribute。对Voucher类进行如下修改:

[Serializable]
public class Voucher
  
  运行NUnit,测试通过,生成的文件内容如下: 


  后面的随笔将会对此文件的格式进行分析。