有时候,我们需要传输比较大的一些数据,自然就想到要”压缩”,但查遍lua的文档,没有压缩的字样. 翻查lod的源码, 发现了隐藏的zlib库,探索一番后,这里做个介绍
源码位于 cust_src\elua\modules\src\lzlib.c
有什么可用的方法
必须先提醒一句,如果数据本身只有几十个字节,压缩后可能更大,而非更小
基本方法
- version() 返回版本号字符串,无参数,总是 返回1.2.8
- adler32(string) 类似crc32的校验和,返回值是int
- crc32(string) 计算crc32,返回值是int
- compress(…) 类似deflate但更简单,个人推荐
- decompress(…) 类似inflate但更简单,个人推荐
流式操作方法
- deflate(…) 新建一个压缩流
- inflate(…) 新建一个解压缩流
- write(…)
- read(…)
- lines(…)
- flush(…)
- close(…)
方法详解
个人觉得最方便的两个方法: compress 和 decompress
这个两个方法都是输入一个string,返回一个string
-- 压缩流程
local bigdata = xxxx -- 一个几kb的数据,未压缩的数据,准备上传
local zlibdata = zlib.compress(bigdata) -- 直接压缩
-- 解压流程
local zlibdata = xxxx -- 一个zlib压缩过的字符串
local rawdata = zlib.decompress(zlibdata) -- 还原为原始未压缩数据
压缩支持更详细的配置,但一般没必要的样子
deflate方法,返回一个压缩流
zlib.deflate(
sink: function | { write: function [, close: function, flush: function] }, -- 输入输出流
compression level, [Z_DEFAILT_COMPRESSION] -- 默认压缩级别
method, [Z_DEFLATED] -- 使用方式,默认是压缩
windowBits, [15]
memLevel, [8] -- 内存占有率
strategy, [Z_DEFAULT_STRATEGY]
)
可以只传第一个参数
inflate方法,返回一个解压流
/*
zlib.inflate(
source: string | function | { read: function, close: function },
windowBits: number, [15]
)
*/
服务器端压缩和解压zlib, 以Java为例
压缩
Deflater compresser = new Deflater();
compresser.setInput(result); // 原始数据
compresser.finish(); // 填充完毕
byte[] result2 = new byte[1024];
int len = compresser.deflate(result2); // 压缩后的数据长度
解压
Inflater decompresser = new Inflater();
decompresser.setInput(buf, 0, buf.length);
byte[] result = new byte[1024];
int resultLength = decompresser.inflate(result); // 解压后的数据长度
decompresser.end();
原版文档: https://github.com/LuaDist/lzlib