关于webservice大数据量传输时的压缩和解压缩

当访问WebSerivice时,如果数据量很大,传输数据时就会很慢。为了提高速度,我们就会想到对数据进行压缩。首先我们来分析一下。

当在webserice中传输数据时,一般都采用Dataset进行数据传输。执行的过程就是先把Dataset转化为xml进行传输,Dataset转化为xml的格式如下:

[html] view plaincopy

  1. <DataSetName>
  2. <DataTableName>
  3. <Column1Name>.......</Column1Name>
  4. <Column2Name>.......</Column2Name>
  5. <Column3Name>.......</Column3Name>
  6. </DataTableName>
  7. ...
  8. ...
  9. ...
  10. <DataSetName>

很明显的可以看到,Datase在t转化为xml的过程中增加了大量的xml格式数据,这样也就加大了传输量。

经过分析,我们就可以找到两个解决数据传输量大的问题的方法:

1.不直接使用Dataset来传输数据,避免转化为xml时增加的额外数据。所以我们可以将Dataset转化为DataSetSurrogate对象用Binary进行序列化,用二进制数据来传输数据。当然你也可以采用其他更好的方式,总之就是减少为了传输而增加的额外数据

2.对数据进行压缩后再传输,至于压缩的方法有很多,可以参考我的文章.net中压缩和解压缩的研究

参考代码如下(这里使用的是.net自带的Gzip进行压缩的,压缩效率可能不是太好):

[html] view plaincopy

  1. //=========================================================================
  2. //类名:DataSetZip
  3. /// <summary>
  4. /// 当DataSet中的数据量很大时,进行网络数据传递时,速度会很慢。
  5. /// 本类将Dataset转化为DataSetSurrogate对象用Binary进行序列化,
  6. /// 然后进行压缩之后进行传输,最后进行解压缩
  7. /// </summary>
  8. /// <remarks>
  9. /// 将DataSet中的DataTable中的数据进行转换或复原
  10. /// </remarks>
  11. /*=========================================================================
  12. 变更记录
  13. 序号       更新日期        开发者      变更内容
  14. 001        2008/7/22       张          新建
  15. =========================================================================*/
  16. public class DataSetZip
  17. {
  18. //消息ID
  19. private const string MSG_ERR_INTERNAL = "MFWE00016";
  20. /// <summary>
  21. /// 取得将DataSet转化为DataSetSurrogate对象用Binary进行序列化,并压缩后的二进制数组
  22. /// </summary>
  23. /// <param name="dsData">需压缩的DataSet数据</param>
  24. /// <returns>压缩后二进制数组</returns>
  25. public static byte[] GetDataSetZipBytes(DataSet dsData)
  26. {
  27. try{
  28. DataSetSurrogate dss = new DataSetSurrogate(dsData);
  29. BinaryFormatter ser = new BinaryFormatter();
  30. MemoryStream ms = new MemoryStream();
  31. ser.Serialize(ms, dss);
  32. byte[] buffer = ms.ToArray();
  33. byte[] Zipbuffer = Compress(buffer);
  34. return Zipbuffer;
  35. }
  36. catch (Exception ex)
  37. {
  38. throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "GetDataSetZipBytes" }, ex, null);
  39. }
  40. }
  41. /// <summary>
  42. /// 用.net自带的Gzip对二进制数组进行压缩,压缩比率可能不是太好
  43. /// </summary>
  44. /// <param name="data">二进制数组</param>
  45. /// <returns>压缩后二进制数组</returns>
  46. public static byte[] Compress(byte[] data)
  47. {
  48. MemoryStream ms = new MemoryStream();
  49. Stream zipStream = null;
  50. zipStream = new GZipStream(ms, CompressionMode.Compress, true);
  51. zipStream.Write(data, 0, data.Length);
  52. zipStream.Close();
  53. ms.Position = 0;
  54. byte[] compressed_data = new byte[ms.Length];
  55. ms.Read(compressed_data, 0, int.Parse(ms.Length.ToString()));
  56. return compressed_data;
  57. }
  58. /// <summary>
  59. /// 对二进制数组进行解压缩
  60. /// </summary>
  61. /// <param name="data">二进制数组</param>
  62. /// <returns>解压缩后的DataSet</returns>
  63. public static DataSet Decompress(byte[] data)
  64. {
  65. try
  66. {
  67. byte[] buffer = null;
  68. MemoryStream zipMs = new MemoryStream(data);
  69. buffer = EtractBytesFormStream(zipMs, data.Length);
  70. BinaryFormatter ser = new BinaryFormatter();
  71. DataSetSurrogate dss = ser.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;
  72. DataSet dsData = dss.ConvertToDataSet();
  73. return dsData;
  74. }
  75. catch(Exception ex)
  76. {
  77. throw new DataSetConverterException(MSG_ERR_INTERNAL, new string[] { "DataSetZip", "Decompress" }, ex, null);
  78. }
  79. }
  80. /// <summary>
  81. /// 用.net自带的Gzip对数据流进行解压缩
  82. /// </summary>
  83. /// <param name="zipMs">数据流</param>
  84. /// <param name="dataBlock">数据长度</param>
  85. /// <returns>解压缩后的二进制数组</returns>
  86. public static byte[] EtractBytesFormStream(MemoryStream zipMs, int dataBlock)
  87. {
  88. byte[] data = null;
  89. int totalBytesRead = 0;
  90. Stream zipStream = null;
  91. zipStream = new GZipStream(zipMs, CompressionMode.Decompress);
  92. while (true)
  93. {
  94. Array.Resize(ref data, totalBytesRead + dataBlock + 1);
  95. int bytesRead = zipStream.Read(data, totalBytesRead, dataBlock);
  96. if (bytesRead == 0)
  97. {
  98. break;
  99. }
  100. totalBytesRead += bytesRead;
  101. }
  102. Array.Resize(ref data, totalBytesRead);
  103. return data;
  104. }
  105. }

关于webservice大数据量传输时的压缩和解压缩

时间: 2024-10-04 02:26:49

关于webservice大数据量传输时的压缩和解压缩的相关文章

大数据量传输时配置WCF的注意事项

原文:大数据量传输时配置WCF的注意事项 WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定的通道上可以接收的消息的最大大小. basicHttpBinding等预定义的绑定一般具有MaxReceivedMessageSize属性,CustomBinding则需要在Transport中定义. 示例代码: <bindings> <custom

解决WCF大数据量传输 ,System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接

开发中所用的数据需要通过WCF进行数据传输,结果就遇到了WCF大量传输问题 也就是提示System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接 网上解决方案都是千篇一律互相转发的,并且没有明确的解决方案或者按照,各个博客中的解决方案都没能解决这个问题. 为此我整整浪费了一天时间用来解决这个问题,而且用了最笨的办法一点点的尝试网上所查到的方案.对于精研WCF来说的这可能是一个小问题,但是对于仅仅了解wcf,一知半解的会很困惑.将解决方案贴出来希望能帮

WCF大数据量传输解决方案

文章内容列表:1. 场景:2. 解决方案3. WCF契约与服务实现设计静态图4. WCF契约与服务实现设计详细说明6. 服务端启动服务代码:7. 客户端代码8.   WCF大数据量传输解决方案源码下载 1. 场景: WCF在网络传输中,大数据量传输造成网络阻塞,宽带无法承受: 2. 解决方案 解决WCF在网络传输中的大数据量问题: A.需要把相关数据序列化成字节流,再对字节流进行压缩,再进行传输,到了客户端再做反向操作便可获得原始数据. B.如果压缩后的数据仍然较大时,可以再压缩流后,再对流进行

hadoop job解决大数据量关联时数据倾斜的一种办法

转自:http://www.cnblogs.com/xuxm2007/archive/2011/09/01/2161929.html http://www.geminikwok.com/2011/04/02/hadoop-job解å?³å¤§æ?°æ?®é??å?³è??æ—¶æ?°æ?®å?¾æ??ç??ä¸?ç§?å??æ³?/ 数据倾斜是指,map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为

java处理大数据量任务时的可用思路--未验证版,具体实现方法有待实践

1.Bloom filter 适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集 基本原理及要点:对于原理来说很简单,位数组+k个独立hash函数.将hash函数对应的值的位数组置1,查找时如果发现所有hash函数对应位都是1说明存在,很明显这个过程并不保证查找的结果是100%正确的.同时也不支持删除一个已经插入的关键字,因为该关键字对应的位会牵动到其他的关键字.所以一个简单的改进就是 counting Bloom filter,用一个counter数组代替位数组,就可以支持删除了.

使用netty4.x客户端接收较大数据量报文时发生的读取不完整bug修复记录

1.先说问题 背景:服务是运行在Linux上的安全网关提供的,TCP协议发送 通过二进制编码的xml字符串 报文,报文头的第一个字段是int类型的表示字节序标记,第二个字段是int类型的表示整个报文长度. 现象:数据量较小时完全可以正常收发报文,当服务端发送的报文数据量较大时(本例是将近600k)概率性出现接收数据直接调用readComplete()方法而没有走channelRead() 跟踪:跟踪代码发现出问题时context 的 read() 方法执行中读取到一百多k(有时两百多也可能三百多

VC++大数据量绘图时无闪烁刷屏技术实现(我的理解是,在内存上作画,然后手动显示,而不再直接需要经过WM_PAINT来处理了)

http://hantayi.blog.51cto.com/1100843/383578 引言 当我们需要在用户区显示一些图形时,先把图形在客户区画上,虽然已经画好但此时我们还无法看到,还要通过 程序主动地刷新用户区,强制Windows发送一条WM_PAINT消息,这将引发视类OnDraw函数简单地将所有的图形对象重画,这样才完成了图形的 显示工作,但在刷新的同时会引起较明显的闪烁尤其是当画面面积较大.图像元素过多时尤为明显甚至达到无法正常工作的地步.因此,我们需要做相应的处理.本 文介绍了采用

使用内存映射文件MMF实现大数据量导出时的内存优化

前言 导出功能几乎是所有应用系统必不可少功能,今天我们来谈一谈,如何使用内存映射文件MMF进行内存优化,本文重点介绍使用方法,相关原理可以参考文末的连接 实现 我们以单次导出一个excel举例(csv同理),excel包含1~n个sheet,在每个sheet中存储的按行和列的坐标在单元格存储具体数据,如果我们要使用MMF,第一个要考虑的就是如何将整个excel合理的存储到MMF中.这里我们引入MMF两个对象: MemoryMappedFile --表示内存映射文件 MemoryMappedVie

.net WebService 大数据量时性能的提高

1.直接返回DataSet对象 C#代码   [WebMethod(Description = "直接返回DataSet对象")] public DataSet GetUserListDateSet() { SqlConnection sqlCon = new SqlConnection("Data Source=.,1444;Initial Catalog=StudyNet;Persist Security Info=True;User ID=**;Password=***