实际应用中,往往需要将Voucher批量保存到磁盘文件,然后发送到业务中心。可以将每个Voucher保存为一个文件,然后将多个文件顺序传输,但这并不是一种很好的方案。
BinnaryFormatter的Serialize方法需要传入一个Stream,这个Stream应当是可以持续写入的,因此将多个Voucher写入同一个stream中,应该是没有问题的。VoucherSerializer的BatchSerialize和BatchDeserialize方法的代码如下:
本文的例子使用的是FileStream,因此在Deserialize的代码中使用 fs.Position != fs.Length代表是否已读到文件尾,但在其他的Stream中,比如NetworkStream,这一逻辑需要适当修改。
NUnit对应的测试代码如下:
TestSerializeVouchers中使用了两个相同的Voucher对象测试,这样做的目的是想分析生成的voucher.data文件的内容:
整个文件的长度为0x01AA字节,从前半部分与后半部分(0x00000000与0x000000D5)的对比可以看出,序列化到同一个流中的多个对象是按序存储的,相互之间不会有任何影响。
BinnaryFormatter的Serialize方法需要传入一个Stream,这个Stream应当是可以持续写入的,因此将多个Voucher写入同一个stream中,应该是没有问题的。VoucherSerializer的BatchSerialize和BatchDeserialize方法的代码如下:
public void BatchSerialize(string filename, Voucher[] vouchers)
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(filename, FileMode.Create);
foreach (Voucher voucher in vouchers)
{
formatter.Serialize(fs, voucher);
}
fs.Close();
}
public Voucher[] BatchDeserialize(string filename)
{
BinaryFormatter formatter = new BinaryFormatter();
ArrayList vouchers = new ArrayList();
FileStream fs = new FileStream(filename, FileMode.Open);
try
{
while (fs.Position != fs.Length)
{
vouchers.Add(formatter.Deserialize(fs));
}
}
finally
{
fs.Close();
}
return (Voucher[])vouchers.ToArray(typeof(Voucher));
}
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream fs = new FileStream(filename, FileMode.Create);
foreach (Voucher voucher in vouchers)
{
formatter.Serialize(fs, voucher);
}
fs.Close();
}
public Voucher[] BatchDeserialize(string filename)
{
BinaryFormatter formatter = new BinaryFormatter();
ArrayList vouchers = new ArrayList();
FileStream fs = new FileStream(filename, FileMode.Open);
try
{
while (fs.Position != fs.Length)
{
vouchers.Add(formatter.Deserialize(fs));
}
}
finally
{
fs.Close();
}
return (Voucher[])vouchers.ToArray(typeof(Voucher));
}
本文的例子使用的是FileStream,因此在Deserialize的代码中使用 fs.Position != fs.Length代表是否已读到文件尾,但在其他的Stream中,比如NetworkStream,这一逻辑需要适当修改。
NUnit对应的测试代码如下:
[Test]
public void TestSerializeVouchers()
{
Voucher[] vouchers = new Voucher[] {new Voucher("2005012900001", "xingd", DateTime.Now), new Voucher("2005012900001", "xingd", DateTime.Now)};
VoucherSerializer serializer = new VoucherSerializer();
serializer.BatchSerialize("voucher.dat", vouchers);
}
[Test]
public void TestDeserializeVouchers()
{
VoucherSerializer serializer = new VoucherSerializer();
Voucher[] vouchers = serializer.BatchDeserialize("voucher.dat");
Assert.AreEqual(vouchers.Length, 2);
Assert.AreEqual(vouchers[0].VoucherId, "2005012900001");
Assert.AreEqual(vouchers[0].Creator, "xingd");
Assert.AreEqual(vouchers[1].VoucherId, "2005012900001");
Assert.AreEqual(vouchers[1].Creator, "xingd");
}
public void TestSerializeVouchers()
{
Voucher[] vouchers = new Voucher[] {new Voucher("2005012900001", "xingd", DateTime.Now), new Voucher("2005012900001", "xingd", DateTime.Now)};
VoucherSerializer serializer = new VoucherSerializer();
serializer.BatchSerialize("voucher.dat", vouchers);
}
[Test]
public void TestDeserializeVouchers()
{
VoucherSerializer serializer = new VoucherSerializer();
Voucher[] vouchers = serializer.BatchDeserialize("voucher.dat");
Assert.AreEqual(vouchers.Length, 2);
Assert.AreEqual(vouchers[0].VoucherId, "2005012900001");
Assert.AreEqual(vouchers[0].Creator, "xingd");
Assert.AreEqual(vouchers[1].VoucherId, "2005012900001");
Assert.AreEqual(vouchers[1].Creator, "xingd");
}
TestSerializeVouchers中使用了两个相同的Voucher对象测试,这样做的目的是想分析生成的voucher.data文件的内容:
整个文件的长度为0x01AA字节,从前半部分与后半部分(0x00000000与0x000000D5)的对比可以看出,序列化到同一个流中的多个对象是按序存储的,相互之间不会有任何影响。