当前位置: 移动技术网 > IT编程>开发语言>c# > .net的序列化与反序列化实例

.net的序列化与反序列化实例

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文实例讲述了.net的序列化与反序列化的实现方法。分享给大家供大家参考。具体方法如下: 1.序列化与反序列化概述 c#中如果需要:将一个结构很复杂的类的对象存储起来,

本文实例讲述了.net的序列化与反序列化的实现方法。分享给大家供大家参考。具体方法如下:

1.序列化与反序列化概述

c#中如果需要:将一个结构很复杂的类的对象存储起来,或者通过网路传输到远程的客户端程序中去,这时就需要用到序列化,反序列化(serialization & deserialization)

2.binaryformattter

.net中串行有三种,binaryformatter, soapformatter和xmlserializer.

其中binaryformattter最简单,它是直接用二进制方式把对象 (object)进行串行或反串,他的优点是速度快,可以串行private或者protected的member, 在不同版本的。net中都兼容,可以看作是。net自己的本命方法,当然缺点也就随之而来了,离开了。net它就活不了,所以不能在其他平台或跨网路上进 行。

3.序列化

复制代码 代码如下:
binaryformatter ser = new binaryformatter();
  memorystream ms = new memorystream();
  ser.serialize(ms, ds);
  byte[] buffer = ms.toarray();

  memorystream :创建其支持存储区为内存的流

4.反序列化

复制代码 代码如下:
//反序列化:将byte[]型的数据,放到stream中,binaryformatter将流中的数据反序列化成对象
  memorystream ms = new memorystream(bytes);
  binaryformatter ser = new binaryformatter();
  datasetsurrogate dss = ser.deserialize(ms) asdatasetsurrogate;

5.完整实例:

复制代码 代码如下:
using system;
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#程序设计有所帮助。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网