180918-JDK之Deflater压缩与Inflater解压
JDK 压缩与解压工具类
在实际的应用场景中,特别是对外传输数据时,将原始数据压缩之后丢出去,可以说是非常常见的一个case了,平常倒是没有直接使用JDK原生的压缩工具类,使用Protosutff和Kryo的机会较多,正好在实际的工作场景中遇到了,现在简单的看下使用姿势
I. 压缩与解压工具类
1. 基本实现
主要借助的就是Deflater, Inflater两个工具类,其使用姿势如下
public static String uncompress(byte[] input) throws IOException {
Inflater inflater = new Inflater();
inflater.setInput(input);
ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
try {
byte[] buff = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buff);
baos.write(buff, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
baos.close();
}
inflater.end();
byte[] output = baos.toByteArray();
return new String(output, "UTF-8");
}
public static byte[] compress(byte[] data) throws IOException {
byte[] output;
Deflater compress = new Deflater();
compress.reset();
compress.setInput(data);
compress.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!compress.finished()) {
int i = compress.deflate(buf);
bos.write(buf, 0, i);
}
output = bos.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
bos.close();
}
compress.end();
return output;
}
一个简单的测试
public static void main(String[] args) throws IOException {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 200; i++) {
builder.append('a' + (new Random().nextInt() * 26));
}
String text = builder.toString();
byte[] compres = compress(text.getBytes());
System.out.println(compres.length + " : " + text.getBytes().length);
String res = uncompress(compres);
System.out.println("uncompress! \n" + text + "\n" + res);
}
输出结果
1011 : 1974
uncompress!
1159641073884270587-148914555-876348695-140903655914152858511750740619-504526839109631208315104321891746743931-228808979-1303586499-19431155411964999751-1784318475-954798177-1812907183-831342707-3149322476028964551802022597-269963287-6384200011467670385844411707877038035412670417-1119826115558346219-959513147646693111435818855-32626587-18184494797054550038966016212145089137523302939171183465807867207-5294746515903446057333959811216956465-11772186456902770294071039871896527261-126190055310658640239029635411410052621945318513-1099749933-2044334159884087065-1705740759-1313321287-1408007761-12659778231544522691472523171153203782987609706919936632357801287155512488271333115291-1121944135941979389-179880545175884207196204559-2097788799145839653133892163716038492252042396151523357607329397509-2453452914618397691174247129-542507633-1893723573237001573-84175562119492726191070559557-875056377-1763237523-662399435-170798495-12405874171550890051-1938474621-701626601-1246867757-1138873077164155271023310391435811251050668025181338411-7641844471088518205-1570482881-1690731767-954924683-213656821149494003-544272515-9322840891981997411254437701-183054198720365002211448655569-54030518916444117051191350451-900732825-2072105047160877226512403288354302424851213478975-57604286986096457192173124564975571096304687-213425653510984804314132356831371957625714091709-327695077-182546427-372769058150182636433743131293942149315625331-1010625457741185365-81246881-565236593-1937214707-2090999425-1673181289-1110250756450022071917863643-127217577910228760391902441297-31318475-535669437-1151216791170962161121375401911260706331-1873591233-495048743-8876731551362670289-686442615-6752584831233249861-3467630691547253127-345092207-908370541-1788351797644350365-67770933-4703179231930520693138257968522450375-1171662023-5791753311816936409-1745781765-922801857281665531707439257928142703-367587763829971705455779401438501763-1398546079-606883161-924403277-1617582925-2005411841279115903
1159641073884270587-148914555-876348695-140903655914152858511750740619-504526839109631208315104321891746743931-228808979-1303586499-19431155411964999751-1784318475-954798177-1812907183-831342707-3149322476028964551802022597-269963287-6384200011467670385844411707877038035412670417-1119826115558346219-959513147646693111435818855-32626587-18184494797054550038966016212145089137523302939171183465807867207-5294746515903446057333959811216956465-11772186456902770294071039871896527261-126190055310658640239029635411410052621945318513-1099749933-2044334159884087065-1705740759-1313321287-1408007761-12659778231544522691472523171153203782987609706919936632357801287155512488271333115291-1121944135941979389-179880545175884207196204559-2097788799145839653133892163716038492252042396151523357607329397509-2453452914618397691174247129-542507633-1893723573237001573-84175562119492726191070559557-875056377-1763237523-662399435-170798495-12405874171550890051-1938474621-701626601-1246867757-1138873077164155271023310391435811251050668025181338411-7641844471088518205-1570482881-1690731767-954924683-213656821149494003-544272515-9322840891981997411254437701-183054198720365002211448655569-54030518916444117051191350451-900732825-2072105047160877226512403288354302424851213478975-57604286986096457192173124564975571096304687-213425653510984804314132356831371957625714091709-327695077-182546427-372769058150182636433743131293942149315625331-1010625457741185365-81246881-565236593-1937214707-2090999425-1673181289-1110250756450022071917863643-127217577910228760391902441297-31318475-535669437-1151216791170962161121375401911260706331-1873591233-495048743-8876731551362670289-686442615-6752584831233249861-3467630691547253127-345092207-908370541-1788351797644350365-67770933-4703179231930520693138257968522450375-1171662023-5791753311816936409-1745781765-922801857281665531707439257928142703-367587763829971705455779401438501763-1398546079-606883161-924403277-1617582925-2005411841279115903
2. 注意事项
上面这个运作的还挺好,但在接入使用时,总是提示java.util.zip.DataFormatException: incorrect header check
, 因为接受的是第三方传递过来的压缩数据,比较坑爹的是对方就写了个Deflater压缩,然后什么都没有了,那么这个是啥原因呢?
其实看下Deflater的构造方法,发现还可以传一个boolean值(nowrap), 官方说明是
/**
* Creates a new compressor using the specified compression level.
* If 'nowrap' is true then the ZLIB header and checksum fields will
* not be used in order to support the compression format used in
* both GZIP and PKZIP.
* @param level the compression level (0-9)
* @param nowrap if true then use GZIP compatible compression
*/
public Deflater(int level, boolean nowrap) {
this.level = level;
this.strategy = DEFAULT_STRATEGY;
this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
}
简单来说,就是压缩时,如果nowrap为true,那么解压时也要为true;否则对不上时,就会抛异常
接下来简单对比下两种不同传参的情况,首先更新下工具类
public static String uncompress(byte[] input, boolean nowrap) throws IOException {
Inflater inflater = new Inflater(nowrap);
inflater.setInput(input);
ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
try {
byte[] buff = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buff);
baos.write(buff, 0, count);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
baos.close();
}
inflater.end();
byte[] output = baos.toByteArray();
return new String(output);
}
public static byte[] compress(byte[] data, boolean nowrap) throws IOException {
byte[] output;
Deflater compress = new Deflater(Deflater.DEFAULT_COMPRESSION, nowrap);
compress.reset();
compress.setInput(data);
compress.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!compress.finished()) {
int i = compress.deflate(buf);
bos.write(buf, 0, i);
}
output = bos.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
bos.close();
}
compress.end();
return output;
}
测试如下
public static void main(String[] args) throws IOException {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
builder.append('a' + (new Random().nextInt() * 26));
}
String text = builder.toString();
byte[] compres = compress(text.getBytes(), true);
System.out.println(compres.length + " : " + text.getBytes().length);
String res = uncompress(compres, true);
System.out.println(res.equals(text));
byte[] compres2 = compress(text.getBytes(), false);
System.out.println(compres2.length + " : " + text.getBytes().length);
String res2 = uncompress(compres2, false);
System.out.println(res2.equals(text));
}
输出结果如下,从大小来看,前者小那么一点点
5086 : 9985
true
5092 : 9985
true
3. 小结
一般来说,jdk自带的压缩与解压,除了方便之外,可能优势并不是那么的大,这里盗一张网上的对比表格
以下来自: [java]序列化框架性能对比(kryo、hessian、java、protostuff)
优点 | 缺点 | |
---|---|---|
kryo | 速度快,序列化后体积小 | 跨语言支持较复杂 |
hessian | 默认支持跨语言 | 较慢 |
protostuff | 速度快,基于protobuf | 需静态编译 |
Protostuff-Runtime | 无需静态编译,但序列化前需预先传入schema | 不支持无默认构造函数的类,反序列化时需用户自己初始化序列化后的对象,其只负责将该对象进行赋值 |
jdk | 使用方便,可序列化所有类 | 速度慢,占空间 |
其次,在使用java的压缩与解压时,需要注意下,nowrap这个参数,需要保持一致,否则会报错
II. 其他
1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
2. 声明
尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840
3. 扫描关注
一灰灰blog
知识星球
180918-JDK之Deflater压缩与Inflater解压的更多相关文章
- 对称加密之AES、压缩解压以及压缩加密解密解压综合实战
AES 压缩解压 压缩加密解密解压 对称加密: 就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密.密钥是控制加密及解密过程的指令.算法是一组规则,规定如何进行加密和解密. 因此加密的安 ...
- PHP zip压缩文件及解压
PHP zip压缩文件及解压 利用ZipArchive 类实现 只有有函数.界面大家自己写 ZipArchive(PHP 5.3 + 已自带不需要安装dll) /** * 文件解压 * @param ...
- SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html
SpringMVC上传压缩文件,解压文件,并检测上传文件中是否有index.html 说明: 1.环境:SpringMVC+Spring+Tomcat7+JDK1.7 2.支持 zip和rar格式的压 ...
- innobackup stream 压缩备份,解压后的qp文件
是用innobackup stream 压缩备份,解压后很多文件还是qp格式的压缩文件,需要再解压. 备份: [root@ ~]# /usr/bin/innobackupex --defaults-f ...
- spring boot 过滤器实现接收 压缩数据 并解压
1.新加类GzipRequestWrapper 继承HttpServletRequestWrapper类 public class GzipRequestWrapper extends HttpSer ...
- linux下分卷压缩,合并解压的3种方法
我们上传东西的时候,由于文件过大而不能上传,或者不给上传,最明显的就是发邮件了,附件最大5M,有的10M.如果超过了就郁闷了.这个时候,如果能把压缩的东西,分割开来就比较爽了,windows下面我想大 ...
- mariadb 最新精简压缩版 win64 解压即用
包含版本: mariadb-10.1.18-winx64 mariadb-5.5.53-winx64 32的没有压缩,估计用的人也比较少. 网盘链接: http://pan.baidu.com/s/1 ...
- linux 中压缩记得压缩用c,解压用x
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- Unity3D研究院之LZMA压缩文件与解压文件
原地址:http://www.xuanyusong.com/archives/3095 前两天有朋友告诉我Unity的Assetbundle是LZMA压缩的,刚好今天有时间那么就研究研究LZMA.它是 ...
随机推荐
- idea插件 总结 自认用比较不错的插件的总结
1.Background Image Plus 设置你喜欢的图片,提升你编码逼格!还可以设置以轮播图的形式变换图片 还可以设置图片的透明度等现实的方式 2.CodeGlance 类似SublimeTe ...
- 解决hibernate双向关系造成的一方重复执行SQl,或者死循环的问题
系统采用struts-json hibernate3. 在对关联表配置manytoone onetomany双向关联的时候,在执行一方的时候,会发现打印出来的SQL语句多执行了一次或者多次.经过调试, ...
- PHP开发者应了解的24个库
@PHP开发者应了解的24个库 本文由 伯乐在线 - 贾朝藤 翻译.未经许可,禁止转载!英文出处:tutorialzine.欢迎加入翻译组. 作为一个PHP开发者,现在是一个令人激动的时刻.每天有许许 ...
- Js 面向对象之封装,继承,原型,原型链
封装 ,继承 ,原型, 原型链 封装 ? 面向对象有三大特性,封装.继承和多态.对于ES5来说,没有class(类)的概念,并且由于JS的函数级作用域(函数内部的变量在函数外访问不到),所以我们就可以 ...
- virtualbox+vagrant学习-3-Vagrant Share-5-Security
Security 可以理解,分享你vagrant环境引发了一些安全问题. vagrant share的主要安全机制是通过隐藏的安全性以及SSH的加密密钥.此外,还有几个配置选项可用来帮助控制访问和管理 ...
- 利用MATLAB软件对数码相机进行检校
分享资料:https://pan.baidu.com/s/1FQb-ttLJNJKlMzu-0RjBsw.内部包含张正友的经典论文等文献,官网的checkerboardPattern等.
- maven3 下载列表
https://archive.apache.org/dist/maven/maven-3/ Parent Directory - 3.0.4/ 2012-09-11 09:37 - 3.0.5/ 2 ...
- 修改Ubuntu从文本界面登录
1, 编辑grup文件 #sudo vim /etc/default/grup //找到这行 GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" / ...
- 【VCS】种草VSCode
VSCode官网 特点:更轻量.集成Git.快速diff:文件目录管理,自定义配置,插件库 种草推文 下载地址 下载安装VSCode之后按照种草推文指南 配置VSC的扩展开发(有个前提:注册了Micr ...
- Yosimite 系统 “发生意外错误(错误代码-50)” (记一次macbook pro(mid2012) 自主维修排错经历)
电脑型号: Macbook Pro(Mid 2012) A1278 问题描述: 上周,电脑偶尔弹出提示框"发生意外错误(错误代码-50)",弹出这个提示之后硬盘好像变成只读模式 ...