随笔 - 126  文章 - 0  评论 - 300 

Android总结之Gzip/Zip压缩

前言:

     做过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

 

posted on 2016-08-20 08:07  总李写代码  阅读(21471)  评论(1编辑  收藏