序列化和传输大型数据流

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

相关文章

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

大型网站架构演化(六)——使用反向代理和CDN加速网站响应

随着网站业务不断发展,用户规模越来越大,由于中国复杂的网络环境,不同地区的用户访问网站时,速度差别也极大。有研究表明,网站访问延迟和用户流失率正相关,网站访问越慢,用户越容易失去耐心而离开。为了提供更好的用户体验,留住用户,网站需要加速网站访问速度。      主要手段:使用CDN和反向代理。如图。     使用CDN和反向代理的目的都是尽早返回数据给用户,一方面加快用户访问速

大型网站架构演化(五)——数据库读写分离

网站在使用缓存后,使绝大部分数据读操作访问都可以不通过数据库就能完成,但是仍有一部分读操作(缓存访问不命中、缓存过期)和全部的写操作需要访问数据库,在网站的用户达到一定规模后,数据库因为负载压力过大而成为网站的瓶颈。      目前豆粉的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。网站利用数据库的这一功能,

大型网站架构演化(四)——使用应用服务器集群改善网站的并发能力

使用集群是网站解决高并发、海量数据问题的常用手段。当一台服务器的处理能力、存储空间不足时,不要企图去更换更强大的服务器,对大型服务器而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。这种情况下,更恰当的做法是增加一台服务器分担原有服务器的访问及存储压力。 对网站架构而言,只要能通过增加一台服务器的方式改善负载压力,就可以以同样的方式持续增加服务器不断改善系统性能,从而实现系统

大型网站架构演化(二)——应用服务和数据服务分离

随着网站业务的发展,一台服务器逐渐不能满足需求:越来越多的用户访问导致性能越来越差,越来越多的数据导致存储空间不足。这时就需要将应用和数据分离。应用和数据分离后整个网站使用三台服务器:应用服务器、文件服务器和数据库服务器,如图。              这三台服务器对硬件资源的要求各不相同: 应用服务器需要处理大量的业务逻辑,因此需要更快更强大的CPU;

大型网站架构演化(一)——初始阶段的网站架构

大型网站的技术挑战主要来自于庞大的用户,高并发的访问和海量的数据,任何简单的业务一旦需要处理数以P计的数据和面对数以亿计的用户,问题就会变得很棘手。大型网站架构主要是解决这类问题。         大型网站都是从小型网站发展而来,网站架构也是一样,是从小型网站架构逐步演化而来。小型网站最开始时没有太多人访问,只需要一台服务器就绰绰有余,这时的网站架构如图所示。

大型网站架构演化(总)

如果把上世纪90年代初CERN正式发布WEB标准和第一个WEB服务的出现当做互联网站的开始,那么互联网站的发展只经历了短短20多年的时间。在20多年的时间里,互联网的世界发生了巨大变化,今天,全球有近一半的人口使用互联网,人们的生活因为互联网而产生了巨大变化。从信息检索到即时通信,从电子购物到文化娱乐,互联网渗透到生活的每个角落,而且这种趋势还在加速。因为互联网,我们的世界正变得越来越小

PHP序列化用到的构造:__sleep() __wakeup()

串行化serialize可以把变量包括对象,转化成连续bytes数据. 你可以将串行化后的变量存在一个文件里或在网络上传输. 然后再反串行化还原为原来的数据. 你在反串行化类的对象之前定义的类,PHP可以成功地存储其对象的属性和方法. 有时你可能需要一个对象在反串行化后立即执行. 为了这样的目的,PHP会自动寻找__sleep和__wakeup方法.   当一个对象被串行化,PHP会

ULTRAINTERACT 数据集与 EURUS 模型:推动开源大型语言模型在推理领域的新进展

在人工智能的浪潮中,大型语言模型(LLMs)已经成为推动自然语言处理技术发展的关键力量。它们在理解、生成语言以及执行复杂任务方面展现出了巨大的潜力。然而,尽管在特定领域内取得了显著进展,现有的开源LLMs在处理多样化和高难度的推理任务时,仍然难以与最前沿的专有模型相媲美。这一差距不仅限制了开源模型的应用范围,也阻碍了整个领域的发展和创新。 推理任务,特别是那些需要综合运用数学知识、编程技能和逻辑

使用 AngularJS 从零构建大型应用

0、导言1、准备工作2、构建框架3、丰富你的directives4、公用的services5、用controllers组织业务 导言 纵览线上各种AngularJS教程,大部分都是基础与一些技巧分析。 如果你已经能运行你的ng-app,但又找不到实际案例可以参考。那么本文应该对您有所帮助。 本文将以电商产品:友好速搭 其中的 店铺后台 作为的实际案例,裸奔展示如何从零构建“自以为大型的”A