摘要:之壓縮與解壓解壓壓縮壓縮與解壓工具類在實(shí)際的應(yīng)用場(chǎng)景中,特別是對(duì)外傳輸數(shù)據(jù)時(shí),將原始數(shù)據(jù)壓縮之后丟出去,可以說是非常常見的一個(gè)了,平常倒是沒有直接使用原生的壓縮工具類,使用和的機(jī)會(huì)較多正好在實(shí)際的工作場(chǎng)景中遇到了,現(xiàn)在簡(jiǎn)單的看下使用姿
title: 180918-JDK之Deflater壓縮與Inflater解壓
tags:
JDK
categories:
Java
JDK
date: 2018-09-18 16:53:13
keywords: JDK,Inflater,Deflater,解壓,壓縮 JDK 壓縮與解壓工具類在實(shí)際的應(yīng)用場(chǎng)景中,特別是對(duì)外傳輸數(shù)據(jù)時(shí),將原始數(shù)據(jù)壓縮之后丟出去,可以說是非常常見的一個(gè)case了,平常倒是沒有直接使用JDK原生的壓縮工具類,使用Protosutff和Kryo的機(jī)會(huì)較多,正好在實(shí)際的工作場(chǎng)景中遇到了,現(xiàn)在簡(jiǎn)單的看下使用姿勢(shì)
I. 壓縮與解壓工具類 1. 基本實(shí)現(xiàn)主要借助的就是Deflater, Inflater兩個(gè)工具類,其使用姿勢(shì)如下
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; }
一個(gè)簡(jiǎn)單的測(cè)試
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! " + text + " " + res); }
輸出結(jié)果
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-20054118412791159032. 注意事項(xiàng)
上面這個(gè)運(yùn)作的還挺好,但在接入使用時(shí),總是提示java.util.zip.DataFormatException: incorrect header check, 因?yàn)榻邮艿氖堑谌絺鬟f過來的壓縮數(shù)據(jù),比較坑爹的是對(duì)方就寫了個(gè)Deflater壓縮,然后什么都沒有了,那么這個(gè)是啥原因呢?
其實(shí)看下Deflater的構(gòu)造方法,發(fā)現(xiàn)還可以傳一個(gè)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)); }
簡(jiǎn)單來說,就是壓縮時(shí),如果nowrap為true,那么解壓時(shí)也要為true;否則對(duì)不上時(shí),就會(huì)拋異常
接下來簡(jiǎn)單對(duì)比下兩種不同傳參的情況,首先更新下工具類
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; }
測(cè)試如下
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)); }
輸出結(jié)果如下,從大小來看,前者小那么一點(diǎn)點(diǎn)
5086 : 9985 true 5092 : 9985 true3. 小結(jié)
一般來說,jdk自帶的壓縮與解壓,除了方便之外,可能優(yōu)勢(shì)并不是那么的大,這里盜一張網(wǎng)上的對(duì)比表格
以下來自: [[java]序列化框架性能對(duì)比(kryo、hessian、java、protostuff)](https://www.cnblogs.com/lonel...
優(yōu)點(diǎn) | 缺點(diǎn) | |
---|---|---|
kryo | 速度快,序列化后體積小 | 跨語(yǔ)言支持較復(fù)雜 |
hessian | 默認(rèn)支持跨語(yǔ)言 | 較慢 |
protostuff | 速度快,基于protobuf | 需靜態(tài)編譯 |
Protostuff-Runtime | 無需靜態(tài)編譯,但序列化前需預(yù)先傳入schema | 不支持無默認(rèn)構(gòu)造函數(shù)的類,反序列化時(shí)需用戶自己初始化序列化后的對(duì)象,其只負(fù)責(zé)將該對(duì)象進(jìn)行賦值 |
jdk | 使用方便,可序列化所有類 | 速度慢,占空間 |
其次,在使用java的壓縮與解壓時(shí),需要注意下,nowrap這個(gè)參數(shù),需要保持一致,否則會(huì)報(bào)錯(cuò)
II. 其他 1. 一灰灰Blog: https://liuyueyi.github.io/he...一灰灰的個(gè)人博客,記錄所有學(xué)習(xí)和工作中的博文,歡迎大家前去逛逛
2. 聲明盡信書則不如,已上內(nèi)容,純屬一家之言,因個(gè)人能力有限,難免有疏漏和錯(cuò)誤之處,如發(fā)現(xiàn)bug或者有更好的建議,歡迎批評(píng)指正,不吝感激
微博地址: 小灰灰Blog
QQ: 一灰灰/3302797840
3. 掃描關(guān)注一灰灰blog
知識(shí)星球
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/77191.html
摘要:將參數(shù)的所有字節(jié)寫入輸出流兩個(gè)允許指定的新構(gòu)造函數(shù)。四個(gè)允許指定的新構(gòu)造函數(shù)。返回從此字符串中提取的行的流,由行終止符分隔。如上所述,使用指定的將字符編碼為字節(jié)。返回此表示的執(zhí)行客戶端中的包裝原因,如果原因不存在或未知,則返回。 有關(guān)API更改的完整列表,可在Github上獲得。 這里列出的是除了java.net.http和jdk.jfr模塊之外的所有新方法。沒有列出java.secu...
摘要:方法根據(jù)子項(xiàng)所處的位置判斷具體類型并返回。調(diào)用方法解除子項(xiàng)與之間的關(guān)聯(lián)。自定義適配器適配器繼承自,并將泛型指定為內(nèi)部類。使用支持多種布局方式借助能夠靈活地將列表控件放入不同的容器。 ListView 和 RecyclerView 最常用和最難用的控件 由于手機(jī)屏幕空間有限,無法顯示全部?jī)?nèi)容。當(dāng)有大量數(shù)據(jù)需要展示的時(shí)候,借助列表控件。通過手指上下滑動(dòng),使得屏幕內(nèi)外的數(shù)據(jù)不斷進(jìn)出。 最基本...
摘要:阿里聚安全的應(yīng)用漏洞掃描服務(wù),可以檢測(cè)出應(yīng)用的文件目錄遍歷風(fēng)險(xiǎn)。阿里聚安全對(duì)開發(fā)者建議對(duì)重要的壓縮包文件進(jìn)行數(shù)字簽名校驗(yàn),校驗(yàn)通過才進(jìn)行解壓。 1、ZIP文件目錄遍歷簡(jiǎn)介 因?yàn)閆IP壓縮包文件中允許存在../的字符串,攻擊者可以利用多個(gè)../在解壓時(shí)改變ZIP包中某個(gè)文件的存放位置,覆蓋掉應(yīng)用原有的文件。如果被覆蓋掉的文件是動(dòng)態(tài)鏈接so、dex或者odex文件,輕則產(chǎn)生本地拒絕服務(wù)漏洞...
閱讀 3162·2023-04-26 02:33
閱讀 3117·2023-04-25 21:33
閱讀 917·2021-09-02 09:56
閱讀 2937·2019-08-30 15:44
閱讀 2468·2019-08-30 13:15
閱讀 1045·2019-08-30 13:04
閱讀 1646·2019-08-29 15:09
閱讀 3978·2019-08-26 18:26