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

 更新时间:2014年10月17日 11:48:30   投稿:shichen2014  
这篇文章主要介绍了.net的序列化与反序列化实例,详细讲述了.net序列化与反序列化的基本原理与用法实例,具有很好的参考借鉴价值,需要的朋友可以参考下

本文实例讲述了.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#程序设计有所帮助。

相关文章

  • 如何在C#中集成Lua脚本

    如何在C#中集成Lua脚本

    这篇文章主要介绍了如何在C#中集成Lua脚本,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • 基于WPF实现颜色选择器控件

    基于WPF实现颜色选择器控件

    这篇文章主要介绍了如何基于WPF实现简单的颜色选择器控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的小伙伴可以参考一下
    2023-08-08
  • c# 动态构建LINQ查询表达式

    c# 动态构建LINQ查询表达式

    这篇文章主要介绍了c# 如何动态构建LINQ查询表达式,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-11-11
  • c#之事件用法

    c#之事件用法

    这篇文章介绍了c#中事件的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C#判断指定驱动器是否是Fat分区格式的方法

    C#判断指定驱动器是否是Fat分区格式的方法

    这篇文章主要介绍了C#判断指定驱动器是否是Fat分区格式的方法,涉及C#中DriveFormat属性的使用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C#实现读取指定盘符硬盘序列号的方法

    C#实现读取指定盘符硬盘序列号的方法

    这篇文章主要介绍了C#实现读取指定盘符硬盘序列号的方法,涉及C#针对硬件属性的相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • C# xml序列化实现及遇到的坑

    C# xml序列化实现及遇到的坑

    在C#中,当我们需要将对象存储到文件或通过网络发送时,我们可以使用XML序列化将C#对象转换为XML文档,以便于存储、传输和还原,本文主要介绍了C# xml序列化实现及遇到的坑,感兴趣的可以了解一下
    2023-09-09
  • C# SendInput 模拟鼠标操作的实现方法

    C# SendInput 模拟鼠标操作的实现方法

    C# SendInput 模拟鼠标操作的实现方法,需要的朋友可以参考一下
    2013-04-04
  • DevExpress实现GridView当无数据行时提示消息

    DevExpress实现GridView当无数据行时提示消息

    这篇文章主要介绍了DevExpress实现GridView当无数据行时提示消息,需要的朋友可以参考下
    2014-08-08
  • Unity3D动态对象优化代码分享

    Unity3D动态对象优化代码分享

    这篇文章主要介绍了Unity3D动态对象优化代码分享的相关资料,需要的朋友可以参考下
    2015-03-03

最新评论