.net的序列化与反序列化实例
本文实例讲述了.net的序列化与反序列化的实现方法。分享给大家供大家参考。具体方法如下:
1.序列化与反序列化概述
c#中如果需要:将一个结构很复杂的类的对象存储起来,或者通过网路传输到远程的客户端程序中去,这时就需要用到序列化,反序列化(serialization & deserialization)
2.binaryformattter
.net中串行有三种,binaryformatter, soapformatter和xmlserializer.
其中binaryformattter最简单,它是直接用二进制方式把对象 (object)进行串行或反串,他的优点是速度快,可以串行private或者protected的member, 在不同版本的。net中都兼容,可以看作是。net自己的本命方法,当然缺点也就随之而来了,离开了。net它就活不了,所以不能在其他平台或跨网路上进 行。
3.序列化
memorystream ms = new memorystream();
ser.serialize(ms, ds);
byte[] buffer = ms.toarray();
memorystream :创建其支持存储区为内存的流
4.反序列化
memorystream ms = new memorystream(bytes);
binaryformatter ser = new binaryformatter();
datasetsurrogate dss = ser.deserialize(ms) asdatasetsurrogate;
5.完整实例:
using system.collections.generic;
using system.text;
using system.io.compression;
using system.io;
namespace common
{
/// <summary>
/// 利用gzipstream进行压缩和解压
/// </summary>
public class gziputil
{
private static gzipstream gzipstream = null;
/// <summary>
/// 压缩
/// </summary>
/// <param name="srcbytes"></param>
/// <returns></returns>
public static byte[] compress(byte[] srcbytes)
{
memorystream ms = new memorystream(srcbytes);
gzipstream = new gzipstream(ms, compressionmode.compress);
gzipstream.write(srcbytes, 0, srcbytes.length);
gzipstream.close();
return ms.toarray();
}
/// <summary>
/// 解压
/// </summary>
/// <param name="srcbytes"></param>
/// <returns></returns>
public static byte[] decompress(byte[] srcbytes)
{
memorystream srcms = new memorystream(srcbytes);
gzipstream = new gzipstream(srcms, compressionmode.decompress);
memorystream ms = new memorystream();
byte[] buffer = new byte[40960];
int n;
while ((n = gzipstream.read(buffer, 0, buffer.length)) > 0)
{
ms.write(buffer, 0, n);
}
gzipstream.close();
return ms.toarray();
}
/// <summary>
/// 将指定的字节数组压缩,并写入到目标文件
/// </summary>
/// <param name="srcbuffer">指定的源字节数组</param>
/// <param name="destfile">指定的目标文件</param>
public static void compressdata(byte[] srcbuffer, string destfile)
{
filestream deststream = null;
gzipstream compressedstream = null;
try
{
//打开文件流
deststream = new filestream(destfile, filemode.openorcreate, fileaccess.write);
//指定压缩的目的流(这里是文件流)
compressedstream = new gzipstream(deststream, compressionmode.compress, true);
//往目的流中写数据,而流将数据写到指定的文件
compressedstream.write(srcbuffer, 0, srcbuffer.length);
}
catch (exception ex)
{
throw new exception(string.format("压缩数据写入文件{0}时发生错误", destfile), ex);
}
finally
{
// make sure we allways close all streams
if (null != compressedstream)
{
compressedstream.close();
compressedstream.dispose();
}
if (null != deststream)
deststream.close();
}
}
/// <summary>
/// 将指定的文件解压,返回解压后的数据
/// </summary>
/// <param name="srcfile">指定的源文件</param>
/// <returns>解压后得到的数据</returns>
public static byte[] decompressdata(string srcfile)
{
if (false == file.exists(srcfile))
throw new filenotfoundexception(string.format("找不到指定的文件{0}", srcfile));
filestream sourcestream = null;
gzipstream decompressedstream = null;
byte[] quartetbuffer = null;
try
{
sourcestream = new filestream(srcfile, filemode.open, fileaccess.read, fileshare.read);
decompressedstream = new gzipstream(sourcestream, compressionmode.decompress, true);
// read the footer to determine the length of the destiantion file
//gzip文件格式说明:
//10字节的头,包含幻数、版本号以及时间戳
//可选的扩展头,如原文件名
//文件体,包括deflate压缩的数据
//8字节的尾注,包括crc-32校验和以及未压缩的原始数据长度(4字节) 文件大小不超过4g
//为data指定byte的长度,故意开大byte数据的范围
//读取未压缩的原始数据长度
quartetbuffer = new byte[4];
long position = sourcestream.length - 4;
sourcestream.position = position;
sourcestream.read(quartetbuffer, 0, 4);
int checklength = bitconverter.toint32(quartetbuffer, 0);
byte[] data;
if (checklength <= sourcestream.length)
{
data = new byte[int16.maxvalue];
}
else
{
data = new byte[checklength + 100];
}
//每100byte从解压流中读出数据,并将读出的数据copy到data byte[]中,这样就完成了对数据的解压
byte[] buffer = new byte[100];
sourcestream.position = 0;
int offset = 0;
int total = 0;
while (true)
{
int bytesread = decompressedstream.read(buffer, 0, 100);
if (bytesread == 0)
break;
buffer.copyto(data, offset);
offset += bytesread;
total += bytesread;
}
//剔除多余的byte
byte[] actualdata = new byte[total];
for (int i = 0; i < total; i++)
actualdata[i] = data[i];
return actualdata;
}
catch (exception ex)
{
throw new exception(string.format("从文件{0}解压数据时发生错误", srcfile), ex);
}
finally
{
if (sourcestream != null)
sourcestream.close();
if (decompressedstream != null)
decompressedstream.close();
}
}
}
}
6.小结
进行序列化,反序列化,利用到的都是binaryformate,都得借普通流memorystream,不同的是:
序列化时,将对象序列化后放到memorystream,而反序列化时,将memorystream中的byte[]数据,反序列成对象
希望本文所述对大家的c#程序设计有所帮助。