Android 数据压缩浅析

 更新时间:2023年03月01日 10:22:47   作者:流浪汉kylin  
这篇文章主要为大家介绍了Android 数据压缩方法浅析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

1. 前言

在开发中我们难免会碰到传输的数据太大,或者传输的资源过大,所以就出现了数据压缩这项技术,现在存在很多种数据压缩的算法,每种算法都有自己的特点和使用场景,这次就想简单来聊聊关于数据压缩这件事。

为什么会想到这个问题,因为碰到了一些场景,我不知道是大家对数据压缩这个概念太模糊不敢去使用,还是因为深思熟虑觉得影响性能太大不想用。我这有个需求,给链接拼接参数,然后跳转这个链接,另外一边从中拿到拼接的参数,其实就是get请求,但是,现在的情况是拼接后的链接又臭又长,就是url?a=xxx&b=xxx&c=xxx......这种,然后就疯狂往后面拼参数。把整个对象拆了往后面拼。那为何不把对象转成json然后压缩呢?

是觉得字符串不能压缩?还是设计时没有意识到还有压缩这事?还是觉得你几十年的开发直觉告诉你使用压缩会出大问题。

2. 关于压缩这件事

首先什么是数据压缩?举个简单的例子,我把AAABBBCCC这个字符串变成3A3B3C,就是一种压缩的思想。

写个Demo演示一下java使用Deflater对字符串进行压缩

public class Test {
    public static String compress(String str) {
        Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
        deflater.setInput(str.getBytes());
        deflater.finish();
        final byte[] bytes = new byte[256];
        ByteArrayOutputStream bos = new ByteArrayOutputStream(256);
        while (!deflater.finished()) {
            int length = deflater.deflate(bytes);
            bos.write(bytes, 0, length);
        }
        deflater.end();
        String result = Base64.encodeToString(bos.toByteArray(), Base64.NO_PADDING);
        Log.v("mmp", "压缩后结果" + result);
        return result;
    }
}

在外部调用

String str = "ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE";
String result = Test.compress(str);

可以看到结果
压缩后结果eNpzdHJ2cXUkhQAATY4NFw

看得出压缩前和压缩后的一个明显的效果。

有人看到这个可能就想到,哦,原来用Base64压缩,这是一个误区,有一定开发经验或者一定基础的朋友都知道,但是可能一些萌新不太熟,我前面也写过了,Base64不是压缩,是一种编码,如果你纯用Base64的话,它只会变得更长。

那为什么还要在这里用Base64呢?Base64是为了将字节数组转成字符串,数据压缩和解压的对象是字节数组,所以压缩可以对字符串压缩,也可以对文件压缩,因为它是针对byte[]

有的人就会说,懂了,那简单,那我图片和视频的压缩也用Deflater。这东西还真不一样,压缩又分为有损压缩和无损压缩,我们上面使用Deflater进行的压缩是无损压缩,是可逆的,而图片和视频的压缩往往会用有损压缩比较多,特别是视频,压缩率很高,因为有损压缩能把数据压得更小,相对得它是不可逆的。所以对数据和资源要使用哪种压缩方式要看具体的场景。比如这里的对字符串压缩,要是使用有损的方式,那解压出来的字符串不就和原字符串内容不同了吗。

相信看到这里,你已经对数据的压缩这个概念有个大概的了解。

3. Deflater算法

前面有说到数据压缩的算法有很多种,甚至你也可以自己设计出一套算法,然后写专利。而Deflater算法是一种常用的数据无损压缩算法。

可以很容易的找到Deflate压缩算法=LZ77+哈夫曼编码,意思是这套算法内部的实现原理就是使用LZ77和哈夫曼编码。

我这边暂时先不讲这些算法的实现过程和原理,因为内容也是比较多,如果以后有时间单独拿出来写,并且手写一遍用代码去实现这些算法(一般都是用C写) ,这里就只简单介绍一下,有个概念就行。

LZ77

LZ77编码是一种基于字典的、“滑动窗”的无损压缩算法。

简单来说就是滑动的过程中,把前面的子串放到字典中,滑动到后面发现相同的子串时只需要替换成子串的位置和长度的信息进去就行。

例如ABCDEFABCDZZZ → ABCDEF(6,4)ZZZ
意思是往前第6个,长度为4。

当然这只是简单的一个体现思路的例子,实际中肯定没有这么简单,比如子串怎么找啊,滑动怎么滑等等之类的。

哈夫曼编码

哈夫曼编码,又涉及到哈夫曼树,贪心算法。该方法完全依据字符出现概率来构造异字头的平均长度最短的码字。

因为这个要根据字符出现的频率构建哈夫曼树,不好简单易懂的演示出来,这里就拿一个别人写的Demo来直接演示效果。

原字符串:BCAADDDCCACACAC

转成二进制后:

10000100100001101000001010000010100010001000100010001000100001101000011010000010100001101000001010000110100000101000011

编码后:1000111110110110100110110110

能看出压缩的效果很明显。

小结

Deflater算法是一种常用的数据压缩算法,其内部是使用LZ77和哈夫曼编码。压缩算法一般都具备平台无关性,它是一种计算,一种思想,java使用的是Deflater这个类,php也有对应的库,go也有对应的库。甚至当你知道了它的原理之后,你也能自己把实现过程给写出来,当然这很麻烦,毕竟涉及算法还是有一定难度。所以一般在开发中你得知道有这么一个东西,它是干嘛的,怎么使用。当然最好还是能知道它的原理,知道它怎么实现的,这并不是毫无作用,当你去学之后,你一定能收获到一些东西。

可以再扩展一下,像图片的质量压缩,就是一种有损压缩的方式,像视频的H264编码,H265编码等,也是一个有损的过程。要心里有个底,对这个数据进行操作,是否需要可逆,是否是针对它的大小,可逆就用无损压缩的算法,为了极致的压缩大小又无所谓不可逆,那就用有损压缩的算法。对数据的传输是否要安全,全都无所谓就明文传输最快,对其大小有要求就压缩,要求安全就加密。开发就这么简单!

GZIP

GZIP也是一种压缩技术,相信很多人都听说过。我们的http请求头中可以配置content-encoding为gzip,那么服务端返回的数据就是经过gzip压缩过之后的数据。那有什么用呢?你文件大,字节数多,传输的速度就慢,我经过gizp压缩之后,压缩率高,传输的字节数少很多,那传输的速度就快。

有的人也会说,那你压缩可解压也是耗时间的啊。说得好,这种我建议你不要信什么原理,直接去实践,去试试使用GZIP压缩和不使用韩国,谁得速度更快。当然数据量大的情况下去测。你会发现哪怕我经过压缩和解压,也比你直接传输的速度更快。

GZIP中的实现也包含了Deflater算法。所以能看出来,压缩算法很多,基本都万变不离其宗,基本都是靠LZ77和哈夫曼,为什么呢?因为别人好用啊,你写不出比它更厉害的,那不用它的用什么。

以上就是Android 数据压缩浅析的详细内容,更多关于Android 数据压缩的资料请关注脚本之家其它相关文章!

相关文章

  • Android 文件夹显示红色叹号的解决方法(必看)

    Android 文件夹显示红色叹号的解决方法(必看)

    下面小编就为大家带来一篇Android 文件夹显示红色叹号的解决方法(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Android手机获取root权限并实现关机重启功能的方法

    Android手机获取root权限并实现关机重启功能的方法

    这篇文章主要介绍了Android手机获取root权限并实现关机重启功能的方法,是Android程序设计中非常重要的技巧,需要的朋友可以参考下
    2014-08-08
  • Android Studio缓存文件夹配置教程

    Android Studio缓存文件夹配置教程

    这篇文章主要为大家详细介绍了Android Studio缓存文件夹配置教程,配置Android Studio的缓存路径,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • android实现session保持简要概述及实现

    android实现session保持简要概述及实现

    其实sesion在浏览器和web服务器直接是通过一个叫做name为sessionid的cookie来传递的,所以只要在每次数据请求时保持sessionid是同一个不变就可以用到web的session了,感兴趣的你可以参考下本文或许对你有所帮助
    2013-03-03
  • Android ListView之EfficientAdapte的使用详解

    Android ListView之EfficientAdapte的使用详解

    这篇文章主要介绍了Android ListView之EfficientAdapte的使用详解的相关资料,这里介绍EfficientAdapter 的使用方法,需要的朋友可以参考下
    2017-08-08
  • Kotlin中单例模式和Java的对比浅析

    Kotlin中单例模式和Java的对比浅析

    目前java中的单例模式有多种写法,kotlin中的写法更多一点,下面这篇文章主要给大家介绍了关于Kotlin中单例模式和Java对比的相关资料,会总结全部的到单例模式写法,需要的朋友可以参考下
    2018-07-07
  • Android数据结构优化教程

    Android数据结构优化教程

    这篇文章主要介绍了Android数据结构优化方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Retrofit网络请求框架之注解解析和动态代理

    Retrofit网络请求框架之注解解析和动态代理

    这篇文章主要介绍了Retrofit网络请求框架之注解解析和动态代理,Retrofit是目前Android平台上比较流行的网络请求框架之一,它提供了一种简洁、灵活的方式来处理HTTP请求和响应
    2023-03-03
  • Android客户端post请求服务器端实例

    Android客户端post请求服务器端实例

    这篇文章主要介绍了Android客户端post请求服务器端实例,本文讲解了Android客户端与服务器端通信方式、解析服务器端返回数据的解释、用GET和POST访问http资源等内容,并给出了一个POST实例,需要的朋友可以参考下
    2015-06-06
  • Android中dataBinding使用的简单封装

    Android中dataBinding使用的简单封装

    前面一段时间学习了一下Android中的DataBinding,但是只是很简单地实现了一下,DataBinding中最强大的地方还没有认真地学习过,有很多地方还不理解,下面这篇文章主要给大家介绍了关于Android中dataBinding使用的简单封装,需要的朋友可以参考下
    2023-06-06

最新评论