前言:
做過Android網絡開發的都知道,在網絡傳輸中我們一般都會開啟GZIP壓縮,但是出於刨根問底的天性僅僅知道如何開啟就不能滿足俺的好奇心的,所以想着寫個demo測試一下比較常用的兩個數據壓縮方式,GZIP/ZIP壓縮。
首先認識一下GZIP壓縮
GZIP是網站壓縮加速的一種技術,對於開啟后可以加快我們網站的打開速度,原理是經過服務器壓縮,客戶端瀏覽器快速解壓的原理,可以大大減少了網站的流量。GZIP最早由Jean-loup Gailly和Mark Adler創建,用於UNIX系統的文件壓縮。我們在Linux中經常會用到后綴為.gz的文件,它們就是GZIP格式的。現今已經成為Internet 上使用非常普遍的一種數據壓縮格式,或者說一種文件格式。HTTP協議上的GZIP編碼是一種用來改進WEB應用程序性能的技術。大流量的WEB站點常常使用GZIP壓縮技術來讓用戶感受更快的速度。這一般是指WWW服務器中安裝的一個功能,當有人來訪問這個服務器中的網站時,服務器中的這個功能就將網頁內容壓縮后傳輸到來訪的電腦瀏覽器中顯示出來.一般對純文本內容可壓縮到原大小的40%.這樣傳輸就快了,效果就是你點擊網址后會很快的顯示出來.當然這也會增加服務器的負載. 一般服務器中都安裝有這個功能模塊的
開GZIP有什么好處?Gzip開啟以后會將輸出到用戶瀏覽器的數據進行壓縮的處理,這樣就會減小通過網絡傳輸的數據量,提高瀏覽的速度。
那么在Android上怎么實現壓縮的呢?相關壓縮api詳見http://www.apihome.cn/api/android/java.util.zip
/** * Gzip 壓縮數據 * * @param unGzipStr * @return */ public static String compressForGzip(String unGzipStr) { if (TextUtils.isEmpty(unGzipStr)) { return null; } try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(baos); gzip.write(unGzipStr.getBytes()); gzip.close(); byte[] encode = baos.toByteArray(); baos.flush(); baos.close(); return Base64Encoder.encode(encode); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Gzip解壓數據 * * @param gzipStr * @return */ public static String decompressForGzip(String gzipStr) { if (TextUtils.isEmpty(gzipStr)) { return null; } byte[] t = Base64Decoder.decodeToBytes(gzipStr); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(t); GZIPInputStream gzip = new GZIPInputStream(in); byte[] buffer = new byte[BUFFERSIZE]; int n = 0; while ((n = gzip.read(buffer, 0, buffer.length)) > 0) { out.write(buffer, 0, n); } gzip.close(); in.close(); out.close(); return out.toString(); } catch (IOException e) { e.printStackTrace(); } return null; }
然后我們再來認識一下ZIP壓縮
ZIP,是一個計算機文件的壓縮的算法,原名Deflate(真空),發明者為菲爾·卡茨(Phil Katz)),他於1989年1月公布了該格式的資料。ZIP通常使用后綴名“.zip”,它的MIME格式為 application/zip 。目前,ZIP格式屬於幾種主流的壓縮格式之一,其競爭者包括RAR格式以及開放源碼的7-Zip格式。從性能上比較,RAR格式較ZIP格式壓縮率較高,而7-Zip由於提供了免費的壓縮工具而逐漸在更多的領域得到應用。
看看具體實現:
/** * Zip 壓縮數據 * * @param unZipStr * @return */ public static String compressForZip(String unZipStr) { if (TextUtils.isEmpty(unZipStr)) { return null; } try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(baos); zip.putNextEntry(new ZipEntry("0")); zip.write(unZipStr.getBytes()); zip.closeEntry(); zip.close(); byte[] encode = baos.toByteArray(); baos.flush(); baos.close(); return Base64Encoder.encode(encode); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Zip解壓數據 * * @param zipStr * @return */ public static String decompressForZip(String zipStr) { if (TextUtils.isEmpty(zipStr)) { return null; } byte[] t = Base64Decoder.decodeToBytes(zipStr); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(t); ZipInputStream zip = new ZipInputStream(in); zip.getNextEntry(); byte[] buffer = new byte[BUFFERSIZE]; int n = 0; while ((n = zip.read(buffer, 0, buffer.length)) > 0) { out.write(buffer, 0, n); } zip.close(); in.close(); out.close(); return out.toString("UTF-8"); } catch (IOException e) { e.printStackTrace(); } return null; }
寫個例子測試一下效果:
List<Person> personList = new ArrayList<>(); int testMaxCount = 500;//測試的最大數據條數 //添加測試數據 for (int i = 0; i < testMaxCount; i++) { Person person = new Person(); person.setAge(i); person.setName(String.valueOf(i)); personList.add(person); } //FastJson生成json數據 String jsonData = JsonUtils.objectToJsonForFastJson(personList); Log.e("MainActivity", "壓縮前json數據 ---->" + jsonData); Log.e("MainActivity", "壓縮前json數據長度 ---->" + jsonData.length()); //Gzip壓縮 long start = System.currentTimeMillis(); String gzipStr = ZipUtils.compressForGzip(jsonData); long end = System.currentTimeMillis(); Log.e("MainActivity", "Gzip壓縮耗時 cost time---->" + (end - start)); Log.e("MainActivity", "Gzip壓縮后json數據 ---->" + gzipStr); Log.e("MainActivity", "Gzip壓縮后json數據長度 ---->" + gzipStr.length()); //Gzip解壓 start = System.currentTimeMillis(); String unGzipStr = ZipUtils.decompressForGzip(gzipStr); end = System.currentTimeMillis(); Log.e("MainActivity", "Gzip解壓耗時 cost time---->" + (end - start)); Log.e("MainActivity", "Gzip解壓后json數據 ---->" + unGzipStr); Log.e("MainActivity", "Gzip解壓后json數據長度 ---->" + unGzipStr.length()); //Zip壓縮 start = System.currentTimeMillis(); String zipStr = ZipUtils.compressForZip(jsonData); end = System.currentTimeMillis(); Log.e("MainActivity", "Zip壓縮耗時 cost time---->" + (end - start)); Log.e("MainActivity", "Zip壓縮后json數據 ---->" + zipStr); Log.e("MainActivity", "Zip壓縮后json數據長度 ---->" + zipStr.length());
運行耗時對比:
數據壓縮比對比:
從上面可以看出兩者壓縮效率和壓縮比相差無幾。可能我測試的數據比較小
接下來看下如何開啟網絡GZIP壓縮
在android 客戶端 request 頭中加入 "Accept-Encoding", "gzip" ,來讓服務器傳送gzip 數據。
具體實現這這里不再做具體介紹分享一個鏈接:http://blog.csdn.net/kepoon/article/details/7482096