欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-16 09:54:52
本文实例讲述了.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#程序设计有所帮助。

上一篇:

下一篇: