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

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

  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进行压缩的,压缩效率可能不是太好):

  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大数据量传输时的压缩和解压缩的更多相关文章

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

    原文:大数据量传输时配置WCF的注意事项 WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMe ...

  2. 【转载】大数据量传输时配置WCF的注意事项

    WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...

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

    开发中所用的数据需要通过WCF进行数据传输,结果就遇到了WCF大量传输问题 也就是提示System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接 网上解决 ...

  4. WCF大数据量传输解决方案

    文章内容列表:1. 场景:2. 解决方案3. WCF契约与服务实现设计静态图4. WCF契约与服务实现设计详细说明6. 服务端启动服务代码:7. 客户端代码8.   WCF大数据量传输解决方案源码下载 ...

  5. WCF大数据量传输配置

    WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...

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

    转自:http://www.cnblogs.com/xuxm2007/archive/2011/09/01/2161929.html http://www.geminikwok.com/2011/04 ...

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

    1.Bloom filter适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集基本原理及要点:对于原理来说很简单,位数组+k个独立hash函数.将hash函数对应的值的位数组置1,查找时如 ...

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

    1.先说问题 背景:服务是运行在Linux上的安全网关提供的,TCP协议发送 通过二进制编码的xml字符串 报文,报文头的第一个字段是int类型的表示字节序标记,第二个字段是int类型的表示整个报文长 ...

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

    http://hantayi.blog.51cto.com/1100843/383578 引言 当我们需要在用户区显示一些图形时,先把图形在客户区画上,虽然已经画好但此时我们还无法看到,还要通过 程序 ...

随机推荐

  1. js文字无缝滚动

    <div id=demo style="overflow:hidden; width:128px; height:300px;"> <div id=demo1&g ...

  2. LongListSelector with bindable SelectedItem

    using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using Microso ...

  3. 读《深入php面向对象、模式与实践》有感(一)

    什么样的代码需要改进?书中给出了四个标准(我个人比较认可这四个标准,实际开发中也的确时常遇到): 一.代码重复 用书中的原话讲:“如果你在写代码的时候,总是感觉似曾相识,很可能你的代码已经重复了”. ...

  4. 无法在提交表单前通过ajax验证解决办法

    博主在一个小项目中,要实现注册表单无刷新验证用户名或密码,但是发现不管怎么样都无法在先通过ajax验证之前不提交表单. 例如:一个简单的验证函数 function check(){ $.post(&q ...

  5. ASPCMS标签教程

    导航栏调用{aspcms:navlist type=0}    <a href="[navlist:link]">[navlist:name]</a>{/a ...

  6. 如何防御“神器”Mimikatz窃取系统密码?

    Mimikatz是一款能够从Windows中获取内存,并且获取明文密码和NTLM哈希值的神器,本文将介绍如何防御这款软件获取密码. Mimikatz介绍 Mimikatz是一款能够从Windows认证 ...

  7. CentOS 安装

    选择选择启动介质 Install or upgrade an existing system: 安装或升级现有的系统 install system with basic video driver: 安 ...

  8. 怎么配置Java环境变量?

    右键计算机 -> 属性 -> 高级系统设置 -> 环境变量,   在系统环境变量添加以下三条变量. 1. PATH, 配置JDK命令文件的位置. 输入“%JAVA_HOME%\bin ...

  9. IOS第九天(3:QQ聊天界面通知的使用)

    #import <Foundation/Foundation.h> #import "Person.h" #import "XQCompany.h" ...

  10. Visual Studio中删除所有空行

    解决方法如下: 使用快捷键Ctrl+H,显示查找和替换视图菜单 Find what(查找内容):^:b*$\n Replace with(替换为):[Empty] (空字符串,什么都不用填) Look ...