序列化和传输大型数据流

2024-06-18 15:48

本文主要是介绍序列化和传输大型数据流,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.前言

理解WCF的序列化形式
掌握DataContractSerializer序列化对象
比较性能
比较xmlSerializer序列化对象
大数据量传输设置
修改配置文件
设置编码
设置流模式
[DataContract]

    

数据契约则是定义服务端和客户端之间要传送的自定义数据类型。
那么该类型就可以被序列化在服务端和客户端之间传送。
类只有声明为[DataContract],该类型的对象才可以被传送,
且只有类的属性会被传送,需要在属性前加[DataMember]声明,这样该属性就可以被序列化传送。
复制代码
[DataContract]   //数据契约声明class MyDataContract{[DataMember]//数据成员标记public string Name{get;  set;}[DataMember]//数据成员标记public string Email{get;   set;}}
复制代码

 

2. WCF服务所支持的序列化器

现在一共是4种:
【1】XmlSerializer
【2】DataContratSerializer
【3】NetDataContractSerializer
【4】DataContractJsonSerializer

2.1 DataContractSerializer 序列化器

    DataContractSerializer 是WCF默认的序列化器:

【1】创建DataContractSerializer实例的方式
指定根类型进行创建,根类型是序列化或反序列化实例的类型。
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));

 

【2】DataContractSerializer序列化方法
WriteObject()  //序列化

        ReadObject()  //反序列化

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;namespace Keasy5.WCF.DataContractSerializers
{public class Person{public string Name { get; set; }public int Age { get; set; }public string Address { get; set; }}class Program{static void Main(string[] args){DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof (Person));MemoryStream memoryStream = new MemoryStream();Person person = new Person(){Name = "ABC",Age = 100,Address = "N/A"};dataContractSerializer.WriteObject(memoryStream, person);//序列换memoryStream.Position = 0;StreamReader streamReader = new StreamReader(memoryStream);string temp = streamReader.ReadToEnd();Console.WriteLine("序列化");Console.WriteLine(temp);Console.WriteLine("序列化");var buffer = System.Text.Encoding.UTF8.GetBytes(temp);MemoryStream memoryStream2 = new MemoryStream(buffer);Person person2 = dataContractSerializer.ReadObject(memoryStream2) as Person; //反序列化Console.WriteLine("姓名:{0}-年龄:{1}-地址:{2}",person2.Name,person2.Age,person2.Address );Console.ReadKey();}}
}

3. 大数据量传输设置

  

  

  3.1 大数据量传输设置

  【1】客户端

    修改客户端接收的最大数据值。

        默认情况下,其接收的最大数据量为65535字节,如超过这个范围,就必须修改默认设置。

     <binding … maxReceivedMessageSize=“999999“>

    或

      bind.MaxReceivedMessageSize = 9999999

 

  【2】WCF服务端

      WCF没有限制服务端发送数据的大小,但可以设置

           serviceBehaviors的dataContractSerializer 的maxItemsInObjectGraph属性,

    用来指定序列化和反序列化对象的最大数目,默认值为65535。

注意:当序列化数组时,每个数组元素当作一个对象
<behaviors><serviceBehaviors><behavior><dataContractSerializer maxItemsInObjectGraph="999999"/></behavior></serviceBehaviors></behaviors>

3.2 本文与二进制

      在大多数情况下,二进制消息量要少于XML本文消息。

        byte[] getFile();

 

3.3 编码

编码方式,跟绑定协议有很大的关系,比如:基于Http协议 编码基本都是TextMessageEncodingBingingElement编码。
【1】TextMessageEncodingBingingElement         
文本消息编码(如:Xml格式),跟其他平台互操作强
    <bindings><wsHttpBinding><binding name="webHttpBinding"messageEncoding="Text"></binding></wsHttpBinding></bindings>

 

【2】MtomMessageEncodingBingingElement  
对消息的部分内容进行二进制进行特殊处理,当传输的数据超过1KB时,可以考虑该编码形式。
<system.serviceModel><bindings><wsHttpBinding><binding name="webHttpBinding"messageEncoding="Mtom"></binding></wsHttpBinding></bindings>
【3】BinaryMessageEncodingBindingElement

       二进制消息编码,基本跟TCP协议有关。

3.4 流模式

当有大量的数据要传输时,WCF中的流模式是整体缓冲和处理内存中消息的默认行为的一个可行的替代方法。

  如果数据无法分段、消息必须以及时的方式传递或者当传输启动时数据尚未完全就绪,则应考虑启用流模式,

  且只能对大型消息(带文本或二进制内容)启用流模式。

    以缓慢的形式传输,需要会话的支持

    当启用流模式后,其他一些特征可能就不能使用了,如:

      不能设置有些安全选项,无法进行可靠性会话。

<bindings><basicHttpBinding><binding name="" transferMode="streaming" /></basicHttpBinding>
</bindings>

  代码形式:

    [ServiceContract]public interface IService1{[OperationContract]Stream RequestInfo();

 

   3.5 大数据量传输--自定义方案

      3.5.1 自定义方案

转成二进制格式
压缩消息内容
切割后分块传递

 

      3.5.2 压缩组件:ICSharpCode.SharpZipLib

        链接: http://pan.baidu.com/s/1qWyPG4W 密码: 1re8

       CompressionHelper.cs

using System;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;namespace CompressDataSet.Common
{/// <summary>/// 压缩强度。/// </summary>public enum CompressionLevel{/// <summary>/// 采用最好的压缩率。/// </summary>BestCompression,/// <summary>/// 采用默认的压缩率。/// </summary>DefaultCompression,/// <summary>/// 采用最快的压缩速度。/// </summary>BestSpeed,/// <summary>/// 不采用任何压缩。/// </summary>NoCompression}/// <summary>/// CompressionHelper 的摘要说明。/// </summary>public class CompressionHelper{/// <summary>/// 获取和设置压缩强度。/// </summary>public CompressionLevel Level;public CompressionHelper(){Level = CompressionLevel.DefaultCompression;}public CompressionHelper(CompressionLevel level){Level = level;}#region Public Methods/// <summary>/// 从原始字节数组生成已压缩的字节数组。/// </summary>/// <param name="bytesToCompress">原始字节数组。</param>/// <returns>返回已压缩的字节数组</returns>public byte[] CompressToBytes(byte[] bytesToCompress){MemoryStream ms = new MemoryStream();Stream s = GetOutputStream(ms);s.Write(bytesToCompress, 0, bytesToCompress.Length);s.Close();return ms.ToArray();}/// <summary>/// 从原始字符串生成已压缩的字符串。/// </summary>/// <param name="stringToCompress">原始字符串。</param>/// <returns>返回已压缩的字符串。</returns>public string CompressToString(string stringToCompress){byte[] compressedData = CompressToBytes(stringToCompress);string strOut = Convert.ToBase64String(compressedData);return strOut;}/// <summary>/// 从原始字符串生成已压缩的字节数组。/// </summary>/// <param name="stringToCompress">原始字符串。</param>/// <returns>返回已压缩的字节数组。</returns>public byte[] CompressToBytes(string stringToCompress){byte[] bytData = Encoding.Unicode.GetBytes(stringToCompress);return CompressToBytes(bytData);}/// <summary>/// 从已压缩的字符串生成原始字符串。/// </summary>/// <param name="stringToDecompress">已压缩的字符串。</param>/// <returns>返回原始字符串。</returns>public string DecompressToString(string stringToDecompress){string outString = string.Empty;if (stringToDecompress == null){throw new ArgumentNullException("stringToDecompress", "You tried to use an empty string");}try{byte[] inArr = Convert.FromBase64String(stringToDecompress.Trim());outString = Encoding.Unicode.GetString(DecompressToBytes(inArr));}catch (NullReferenceException nEx){return nEx.Message;}return outString;}/// <summary>/// 从已压缩的字节数组生成原始字节数组。/// </summary>/// <param name="bytesToDecompress">已压缩的字节数组。</param>/// <returns>返回原始字节数组。</returns>public byte[] DecompressToBytes(byte[] bytesToDecompress){byte[] writeData = new byte[4096];Stream s2 = GetInputStream(new MemoryStream(bytesToDecompress));MemoryStream outStream = new MemoryStream();while (true){int size = s2.Read(writeData, 0, writeData.Length);if (size > 0){outStream.Write(writeData, 0, size);}else{break;}}s2.Close();byte[] outArr = outStream.ToArray();outStream.Close();return outArr;}#endregion#region Private Methods/// <summary>/// 根据压缩强度返回使用了不用压缩算法的 Deflate 对象。/// </summary>/// <param name="level">压缩强度。</param>/// <returns>返回使用了不用压缩算法的 Deflate 对象。</returns>private Deflater GetDeflater(CompressionLevel level){switch (level){case CompressionLevel.DefaultCompression:return new Deflater(Deflater.DEFAULT_COMPRESSION);case CompressionLevel.BestCompression:return new Deflater(Deflater.BEST_COMPRESSION);case CompressionLevel.BestSpeed:return new Deflater(Deflater.BEST_SPEED);case CompressionLevel.NoCompression:return new Deflater(Deflater.NO_COMPRESSION);default:return new Deflater(Deflater.DEFAULT_COMPRESSION);}}/// <summary>/// 从给定的流生成压缩输出流。/// </summary>/// <param name="inputStream">原始流。</param>/// <returns>返回压缩输出流。</returns>private DeflaterOutputStream GetOutputStream(Stream inputStream){return new DeflaterOutputStream(inputStream, GetDeflater(Level));}/// <summary>/// 从给定的流生成压缩输入流。/// </summary>/// <param name="inputStream">原始流。</param>/// <returns>返回压缩输入流。</returns>private InflaterInputStream GetInputStream(Stream inputStream){return new InflaterInputStream(inputStream);}#endregion}
}
using System;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;namespace CompressDataSet.Common
{/// <summary>/// 压缩强度。/// </summary>public enum CompressionLevel{/// <summary>/// 采用最好的压缩率。/// </summary>BestCompression,/// <summary>/// 采用默认的压缩率。/// </summary>DefaultCompression,/// <summary>/// 采用最快的压缩速度。/// </summary>BestSpeed,/// <summary>/// 不采用任何压缩。/// </summary>NoCompression}/// <summary>/// CompressionHelper 的摘要说明。/// </summary>public class CompressionHelper{/// <summary>/// 获取和设置压缩强度。/// </summary>public CompressionLevel Level;public CompressionHelper(){Level = CompressionLevel.DefaultCompression;}public CompressionHelper(CompressionLevel level){Level = level;}#region Public Methods/// <summary>/// 从原始字节数组生成已压缩的字节数组。/// </summary>/// <param name="bytesToCompress">原始字节数组。</param>/// <returns>返回已压缩的字节数组</returns>public byte[] CompressToBytes(byte[] bytesToCompress){MemoryStream ms = new MemoryStream();Stream s = GetOutputStream(ms);s.Write(bytesToCompress, 0, bytesToCompress.Length);s.Close();return ms.ToArray();}/// <summary>/// 从原始字符串生成已压缩的字符串。/// </summary>/// <param name="stringToCompress">原始字符串。</param>/// <returns>返回已压缩的字符串。</returns>public string CompressToString(string stringToCompress){byte[] compressedData = CompressToBytes(stringToCompress);string strOut = Convert.ToBase64String(compressedData);return strOut;}/// <summary>/// 从原始字符串生成已压缩的字节数组。/// </summary>/// <param name="stringToCompress">原始字符串。</param>/// <returns>返回已压缩的字节数组。</returns>public byte[] CompressToBytes(string stringToCompress){byte[] bytData = Encoding.Unicode.GetBytes(stringToCompress);return CompressToBytes(bytData);}/// <summary>/// 从已压缩的字符串生成原始字符串。/// </summary>/// <param name="stringToDecompress">已压缩的字符串。</param>/// <returns>返回原始字符串。</returns>public string DecompressToString(string stringToDecompress){string outString = string.Empty;if (stringToDecompress == null){throw new ArgumentNullException("stringToDecompress", "You tried to use an empty string");}try{byte[] inArr = Convert.FromBase64String(stringToDecompress.Trim());outString = Encoding.Unicode.GetString(DecompressToBytes(inArr));}catch (NullReferenceException nEx){return nEx.Message;}return outString;}/// <summary>/// 从已压缩的字节数组生成原始字节数组。/// </summary>/// <param name="bytesToDecompress">已压缩的字节数组。</param>/// <returns>返回原始字节数组。</returns>public byte[] DecompressToBytes(byte[] bytesToDecompress){byte[] writeData = new byte[4096];Stream s2 = GetInputStream(new MemoryStream(bytesToDecompress));MemoryStream outStream = new MemoryStream();while (true){int size = s2.Read(writeData, 0, writeData.Length);if (size > 0){outStream.Write(writeData, 0, size);}else{break;}}s2.Close();byte[] outArr = outStream.ToArray();outStream.Close();return outArr;}#endregion#region Private Methods/// <summary>/// 根据压缩强度返回使用了不用压缩算法的 Deflate 对象。/// </summary>/// <param name="level">压缩强度。</param>/// <returns>返回使用了不用压缩算法的 Deflate 对象。</returns>private Deflater GetDeflater(CompressionLevel level){switch (level){case CompressionLevel.DefaultCompression:return new Deflater(Deflater.DEFAULT_COMPRESSION);case CompressionLevel.BestCompression:return new Deflater(Deflater.BEST_COMPRESSION);case CompressionLevel.BestSpeed:return new Deflater(Deflater.BEST_SPEED);case CompressionLevel.NoCompression:return new Deflater(Deflater.NO_COMPRESSION);default:return new Deflater(Deflater.DEFAULT_COMPRESSION);}}/// <summary>/// 从给定的流生成压缩输出流。/// </summary>/// <param name="inputStream">原始流。</param>/// <returns>返回压缩输出流。</returns>private DeflaterOutputStream GetOutputStream(Stream inputStream){return new DeflaterOutputStream(inputStream, GetDeflater(Level));}/// <summary>/// 从给定的流生成压缩输入流。/// </summary>/// <param name="inputStream">原始流。</param>/// <returns>返回压缩输入流。</returns>private InflaterInputStream GetInputStream(Stream inputStream){return new InflaterInputStream(inputStream);}#endregion}
}

这篇关于序列化和传输大型数据流的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072424

相关文章

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

数据流与Bitmap之间相互转换

把获得的数据流转换成一副图片(Bitmap) 其原理就是把获得倒的数据流序列化到内存中,然后经过加工,在把数据从内存中反序列化出来就行了。 难点就是在如何实现加工。因为Bitmap有一个专有的格式,我们常称这个格式为数据头。加工的过程就是要把这个数据头与我们之前获得的数据流合并起来。(也就是要把这个头加入到我们之前获得的数据流的前面)      那么这个头是

Python---文件IO流及对象序列化

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 前文模块中提到加密模块,本文将终点介绍加密模块和文件流。 一、文件流和IO流概述         在Python中,IO流是用于输入和输出数据的通道。它可以用于读取输入数据或将数据写入输出目标。IO流可以是标准输入/输出流(stdin和stdout),也可以是文件流,网络流等。

微信小程序(一)数据流与数据绑定

一、单向数据流和双向数据流 1、单项数据流:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面 优点:数据跟踪方便,流向单一,追寻问题比较方便【主要体现:微信小程序】。 缺点:就是写起来不太方便,如果修改UI界面数据需要维护对应的model对象 2、双向数据流:值和UI是双向绑定的,大家都知道,只要UI里面的值发生

jquery 表单序列化

jQuery序列化表单的方法总结 现在这里贴出案例中静态的html网页内容: <!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8"><title>Title</title><script src="../js/jquery-3.2.1.js"></script></head><body><form method="post"

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1)getTransletInstance2)defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码,但由于defineClas

Spring之——整合Redis序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer

当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedisTemplate默认使用的是StringRedisSerializer。 Spring Data JPA为我们提供了下面的Serializ

远程桌面文件传输异常或者取消传输后一直显示正在取消

环境: Window Servers 2008 R2 摘要说明: 本篇文章主要讲述当应用远程桌面进行文件传输时,若因网络等导致进程中断,再次传输时则不能进行文件传输;或者传输时取消传输,然后一直显示正在取消。此时可以通过重启window的rdpclip.exe进程来解决此问题 步骤 1.关闭rdpclip.exe进程 远程桌面连上上传输异常的服务器,打开资源管理器,在进程列关闭rdpc