最近在忙一个xmpp协议的项目,用到了zlib流式压缩(我很菜,第一次听说),搞了一阵子乌龙事件,就是没有分清楚一次性压缩和流式压缩。幸好,经过一晚上琢磨搞明白了,记录下,顺便帮助其他人。如有不对,请指教。

首先,有2个概念要分清楚:片段压缩和流式压缩。

片段压缩:或者叫一次性压缩,就像给你一个mp3文件,你直接zip压缩了,这就是一次性压缩

流式压缩:同样给你一个mp3文件,但是每10秒压缩一个小包,总共下来很多个小包。而且这些小包是连续的,不会中断

最后的效果就是,不管哪一种压缩方式都能完整不间断的听完这个mp3。

既然如此为不直接用第一个方法,岂不是更省事?

理由有下(自己总结的,不一定准确,仅供参考):

  1. 如果数据非常大,压缩完了还是很大,一次性发送不方便
  2. 有些场景下不支持TLS加密通信,就需要压缩支持(XMPP官方文档如此描述)

这里,用到了zlib库,zlib是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发。zlib初版0.9版在1995年5月1日发表。zlib使用DEFLATE算法,最初是为libpng函式库所写的,后来普遍为许多软件所使用。此函式库为自由软件,使用zlib授权。截至2007年3月,zlib是包含在Coverity的美国国土安全部赞助者选择继续审查的开源项目。

网上可以找到很多zlib的案例,但是python的比较短缺,尤其没讲清楚怎么个流压缩,因为试图用片段压缩代替流压缩是行不通的,下面会讲到为什么。

先看看python版zlib片段压缩:

# -*- coding: utf-8 -*-
import zlibto_decom = []
for a in ['xmpp','demo']:com_data = zlib.compress(a.encode())to_decom.append(com_data)print([i for i in com_data])for aa in to_decom:de_data = zlib.decompress(aa)print(de_data.decode())# 执行结果
# [120, 156, 171, 200, 45, 40, 0, 0, 4, 123, 1, 198]
# [120, 156, 75, 73, 205, 205, 7, 0, 4, 12, 1, 166]
# xmpp
# demo

可以看到每个分段都是独立压缩的,[120,156]是压缩头,作为一段压缩数据的开始,每个压缩数据都有则说明这些数据是分散的,不是连续的。在看另一个例子:

# -*- coding: utf-8 -*-
import zlibto_decom = []
for a in ['xmpp','demo']:compressor = zlib.compressobj()com_data = compressor.compress(a.encode())com_data += compressor.flush(zlib.Z_SYNC_FLUSH)to_decom.append(com_data)print([i for i in com_data])for aa in to_decom:decompressor = zlib.decompressobj()de_data = decompressor.decompress(aa)de_data += decompressor.flush(zlib.Z_SYNC_FLUSH)print(de_data.decode())# 执行结果
# [120, 156, 170, 200, 45, 40, 0, 0, 0, 0, 255, 255]
# [120, 156, 74, 73, 205, 205, 7, 0, 0, 0, 255, 255]
# xmpp
# demo

这次改用流压缩了,注意[120,156]头数据和[0,0,255,255]尾数据都是一致的,这说明这2个压缩也是独立的,只不过每个压缩自己是流的。那怎么将多个数据或者说一个很长很长的数据分段压缩成流呢?也就是说压缩后的数据不间断,即是在xmpp中压缩所需要的方法:流压缩。因为xmpp本身就是stream流,stream也是自始至终只有一个开始头:<stream:stream>和一个结尾:</stream:stream>,中间的所有信令往来都是中间的流。就像看一部电影一样,整个电影只有一个开场白和一个结束语,中间不管暂停多少次,都不影响连续播放。这里也是一个道理,不管数据多长,每次都压缩一点,并且告诉接收方,这是一小段,接着上一段。

要实现流压缩其实也不难,就是让压缩对象本身不中断:

# -*- coding=utf-8 -*-
import zlibclass Client:def __init__(self):self.compressor = zlib.compressobj()def run(self,datas,buff=2):data = self.compressor.compress(datas[:buff].encode())datas = datas[buff:]while datas:data += self.compressor.compress(datas[:buff].encode())datas = datas[buff:]data += self.compressor.flush(zlib.Z_SYNC_FLUSH)return dataif __name__ == '__main__':client = Client()data = client.run('xmpp')print([i for i in data])data = client.run('dem')print([i for i in data])# 执行结果# [120, 156, 170, 200, 45, 40, 0, 0, 0, 0, 255, 255]# [74, 73, 205, 5, 0, 0, 0, 255, 255]

这里采用了每次只压缩2个字符长度,但是整个数据压缩仍是完整的,对比上图,发现,只有第一段数据有[120,156]头,往后的数据都没有头了,这就是说明数据是连接着的,没有另起炉灶。但是每个数据压缩结尾都有一个[0,0,255,255]数据是为啥?这是告诉接收方,一个小片段流到这结束了,你可以先解压了,不用等了(因为是长链接),然后再来一个小片段没有头,就发现是接着上一次的。

这里最主要的区别就是compressor对象没有释放。同样解压也是一个道理。

好了,简单就这些,我也是第一次接触这块,也是小白,肯能有说的不对的地方,大家批判接受!

python数据压缩和流压缩-zlib相关推荐

  1. Python数据压缩和存档——zlib/gzip/bzip2/lzma/zip/tar

    Python数据压缩和存档--zlib/gzip/bzip2/lzma/zip/tar 原始文档:https://www.yuque.com/lart/ppqg89/gp3q6t 前言 python ...

  2. python xmxl 无法启动_/usr/bin/python: can't decompress data; zlib not available 的异常处理

    1. 问题背景 使用Pycharm连接远程服务器端pipenv虚拟环境的python解释器,运行python spark脚本时报错如下错误: 2018-09-12 23:56:00 ERROR Exe ...

  3. python向服务器请求压缩数据及解压缩数据

    向服务器请求压缩数据格式,并解压缩数据 #!/usr/bin/env python # encoding=utf-8import urllib2, httplibdef writeFile(fname ...

  4. python的tarfile模块实例 python把文件夹压缩成tar格式文件的例子

    本节主要内容: python的tarfiel模块实例. 使用tarfile模块压缩文件. 例子,使用python中的tarfile压缩文件夹. 代码: 复制代码代码示例: #!/bin/python ...

  5. windows下ffmpeg+nginx-rtmp环境搭建及opencv+ffmpeg+python实现拉流和rtmp直播推流

    由于工作需要最近在研究rtsp拉流与直播推流的问题,目前先在我本机上进行了实验,本博客记录学习的内容,包含windows下ffmpeg.nginx-rtmp环境搭建及opencv+ffmpeg+pyt ...

  6. python工作任务流flow实时框架:prefect

    python工作任务流flow实时框架:prefect prefect是一个python的工作任务流调度实时框架,prefect可以快速构建平台系统复杂模块间工作流的监测.当平台系统模块之间的调用链越 ...

  7. 用python做PDF本地化压缩,新增多进程

    用python做PDF压缩 虽然现在有很多成熟的工具了,但是就是想自己捣鼓一下 在网上找了一圈,发现实现方法有两种,一种是需要联网上传(TinyPNG的API)压缩的,一种是本地用python算法 这 ...

  8. python交通调查数据处理_基于Python的交通流数据清洗

    龙源期刊网 http://www.qikan.com.cn 基于 Python 的交通流数据清洗 作者:李红梅 唐岚 来源:<电子技术与软件工程> 2016 年第 09 期 [关键词]交通 ...

  9. Python解压7z压缩文件

    Python解压7z压缩文件 可以使用py7zr库: import py7zrarchive = py7zr.SevenZipFile(r'xxx.7z', mode='r')archive.extr ...

最新文章

  1. Asp.net支持三种类型的cache[转]
  2. 江行智能CTO樊小毅:AI+边缘计算驱动能源产业变革 | 量子位·视点分享回顾
  3. CORS with Spring MVC--转
  4. OpenGL 本机MSAA的实例
  5. python观察日志(part24)--列表和numpy数组扁平化
  6. Android之三大图片缓存原理、特性对比
  7. windows故障转移群集和mysql_Windows 2016 无域故障转移群集部署方法 超详细图文教程...
  8. Python的WSGI
  9. python import random_python import random 后一直无法使用解决方法
  10. 深入Linux内核架构(中文版)pdf
  11. 88个塑胶模具设计中常用的知识点
  12. java数据库同步_Java数据同步
  13. web聊天界面html,PC端Web聊天界面+代码分享(HTML+CSS)
  14. PCB天线和陶瓷天线
  15. 全球服务器系统排行,服务器操作系统排行榜
  16. EverEdit 4.2.0.4457 免安装已激活 x64
  17. 在Windows下批量修改文件后缀(ren命令-rename)
  18. Java实现人物拼图游戏
  19. Silvaco TCAD仿真5——process simulation(Athena)
  20. Why we need activation function?

热门文章

  1. 一个资深HR的忠告:用邮箱发简历的注意事项
  2. hacker.pcapng解析
  3. 遍历100以内的所有质数
  4. mac软件linux系统,Linux/MAC OSX 开机程序
  5. react中使用动画 react-transition-group
  6. 如何将无线路由器设置为AP模式-Genie管理界面
  7. 舆情监控系统哪家做的更好?
  8. 小白立创机械狗从零到成品总结
  9. 使用Flask搭建一个流媒体服务器
  10. SQL Server的数据排序