国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C# > 正文

.net的序列化與反序列化實(shí)例

2020-01-24 02:21:11
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例講述了.net的序列化與反序列化的實(shí)現(xiàn)方法。分享給大家供大家參考。具體方法如下:

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

C#中如果需要:將一個(gè)結(jié)構(gòu)很復(fù)雜的類的對(duì)象存儲(chǔ)起來(lái),或者通過(guò)網(wǎng)路傳輸?shù)竭h(yuǎn)程的客戶端程序中去,這時(shí)就需要用到序列化,反序列化(Serialization & Deserialization)

2.BinaryFormattter

.NET中串行有三種,BinaryFormatter, SoapFormatter和XmlSerializer.

其中BinaryFormattter最簡(jiǎn)單,它是直接用二進(jìn)制方式把對(duì)象 (Object)進(jìn)行串行或反串,他的優(yōu)點(diǎn)是速度快,可以串行private或者protected的member, 在不同版本的。NET中都兼容,可以看作是。NET自己的本命方法,當(dāng)然缺點(diǎn)也就隨之而來(lái)了,離開(kāi)了。NET它就活不了,所以不能在其他平臺(tái)或跨網(wǎng)路上進(jìn) 行。

3.序列化

復(fù)制代碼 代碼如下:
BinaryFormatter ser = new BinaryFormatter();
  MemoryStream ms = new MemoryStream();
  ser.Serialize(ms, DS);
  byte[] buffer = ms.ToArray();

  MemoryStream :創(chuàng)建其支持存儲(chǔ)區(qū)為內(nèi)存的流

4.反序列化

復(fù)制代碼 代碼如下:
//反序列化:將byte[]型的數(shù)據(jù),放到Stream中,BinaryFormatter將流中的數(shù)據(jù)反序列化成對(duì)象
  MemoryStream ms = new MemoryStream(bytes);
  BinaryFormatter ser = new BinaryFormatter();
  DataSetSurrogate dss = ser.Deserialize(ms) asDataSetSurrogate;

5.完整實(shí)例:

復(fù)制代碼 代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Compression;
using System.IO;

namespace Common
{
    /// <summary>
    /// 利用GzipStream進(jìn)行壓縮和解壓
    /// </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>
        /// 將指定的字節(jié)數(shù)組壓縮,并寫(xiě)入到目標(biāo)文件
        /// </summary>
        /// <param name="srcBuffer">指定的源字節(jié)數(shù)組</param>
        /// <param name="destFile">指定的目標(biāo)文件</param>
        public static void CompressData(byte[] srcBuffer, string destFile)
        {
            FileStream destStream = null;
            GZipStream compressedStream = null;
            try
            {
                //打開(kāi)文件流
                destStream = new FileStream(destFile, FileMode.OpenOrCreate, FileAccess.Write);
                //指定壓縮的目的流(這里是文件流)
                compressedStream = new GZipStream(destStream, CompressionMode.Compress, true);
                //往目的流中寫(xiě)數(shù)據(jù),而流將數(shù)據(jù)寫(xiě)到指定的文件
                compressedStream.Write(srcBuffer, 0, srcBuffer.Length);
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("壓縮數(shù)據(jù)寫(xiě)入文件{0}時(shí)發(fā)生錯(cuò)誤", destFile), ex);
            }
            finally
            {
                // Make sure we allways close all streams              
                if (null != compressedStream)
                {
                    compressedStream.Close();
                    compressedStream.Dispose();
                }

                if (null != destStream)
                    destStream.Close();
            }
        }
        /// <summary>
        /// 將指定的文件解壓,返回解壓后的數(shù)據(jù)
        /// </summary>
        /// <param name="srcFile">指定的源文件</param>
        /// <returns>解壓后得到的數(shù)據(jù)</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文件格式說(shuō)明:
                //10字節(jié)的頭,包含幻數(shù)、版本號(hào)以及時(shí)間戳
                //可選的擴(kuò)展頭,如原文件名
                //文件體,包括DEFLATE壓縮的數(shù)據(jù)
                //8字節(jié)的尾注,包括CRC-32校驗(yàn)和以及未壓縮的原始數(shù)據(jù)長(zhǎng)度(4字節(jié)) 文件大小不超過(guò)4G

                //為Data指定byte的長(zhǎng)度,故意開(kāi)大byte數(shù)據(jù)的范圍
                //讀取未壓縮的原始數(shù)據(jù)長(zhǎng)度
                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從解壓流中讀出數(shù)據(jù),并將讀出的數(shù)據(jù)Copy到Data byte[]中,這樣就完成了對(duì)數(shù)據(jù)的解壓
                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}解壓數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤", srcFile), ex);
            }
            finally
            {
                if (sourceStream != null)
                    sourceStream.Close();

                if (decompressedStream != null)
                    decompressedStream.Close();
            }
        }

    }
}

6.小結(jié)

進(jìn)行序列化,反序列化,利用到的都是BinaryFormate,都得借普通流MemoryStream,不同的是:

序列化時(shí),將對(duì)象序列化后放到MemoryStream,而反序列化時(shí),將MemoryStream中的byte[]數(shù)據(jù),反序列成對(duì)象

希望本文所述對(duì)大家的C#程序設(shè)計(jì)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 襄城县| 万安县| 江安县| 永济市| 福州市| 呼伦贝尔市| 苏尼特右旗| 金溪县| 阿鲁科尔沁旗| 鹿泉市| 镇赉县| 阳信县| 永吉县| 太仆寺旗| 平潭县| 博野县| 商都县| 临武县| 临夏市| 开封市| 桓仁| 三河市| 凯里市| 图们市| 长春市| 花莲市| 高台县| 垣曲县| 淮阳县| 梅河口市| 咸阳市| 岳普湖县| 赤峰市| 昌图县| 崇左市| 和顺县| 东乡族自治县| 武隆县| 四会市| 阳信县| 永新县|