添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 【我的Android进阶之旅】Android实现中文汉字笔划(笔画)排序、中文拼音排序、英文排序的国家地区选择界面
  • 【我的Java开发学习之旅】如何实现中文汉字进行笔划(笔画)排序?
  • https://github.com/ouyangpeng/ChinesePinyinSortAndStrokeSort
  • 其中优化之后,将数据库的内容,序列化成为了json数据,然后通过解析json数据,拿到汉字笔画的相关信息。但是未处理前的json文件,体积较大,有2.13Mb,因此需要压缩才行。

    部分数据如下所示:

    "33828" : { "code" : "33828" , "name" : "萤" , "order" : "7298" , "strokeSum" : "11" "22920" : { "code" : "22920" , "name" : "妈" , "order" : "1051" , "strokeSum" : "6" "20718" : { "code" : "20718" , "name" : "僮" , "order" : "13341" , "strokeSum" : "14" "30615" : { "code" : "30615" , "name" : "瞗" , "order" : "15845" , "strokeSum" : "16" "36969" : { "code" : "36969" , "name" : "適" , "order" : "13506" , "strokeSum" : "14"

    二、常规压缩json

    2.1 未处理前的json文件

    未处理前的json文件,格式好看但是体积较大。

    在这里插入图片描述
    未处理前的json文件,一共占用125414行
    在这里插入图片描述

    未处理的原始json文件大小为2.13Mb
    在这里插入图片描述

    2.2 将JSON压缩成一行,去掉换行和空格字符

    在Android Studio中打开,如下所示:

    将JSON压缩成一行,去掉换行和空格字符后的json文件大小为:1.39Mb,只之前的2.13Mb小了整整0.74Mb,这个在移动端是很可观的优化!

    2.3 将JSON的key进行缩短

    json 是 key-value 结构,如果定义好规范,则可以将 key 尽量缩短,甚至是无意义的字母,但前提是文档一定要写清楚,避免不必要的麻烦。

    比如之前的 key-value结构如下所示:
    在这里插入图片描述

    "33828" : { "code" : "33828" , "name" : "萤" , "order" : "7298" , "strokeSum" : "11" "22920" : { "code" : "22920" , "name" : "妈" , "order" : "1051" , "strokeSum" : "6" "20718" : { "code" : "20718" , "name" : "僮" , "order" : "13341" , "strokeSum" : "14" "30615" : { "code" : "30615" , "name" : "瞗" , "order" : "15845" , "strokeSum" : "16" "36969" : { "code" : "36969" , "name" : "適" , "order" : "13506" , "strokeSum" : "14"

    现在我们将key进行优化,使用

    c 代替 code
    n 代替 name
    o 代替 order
    s 代替 strokeSum

    当然这样key的名字变化了,对应解析Json的java实体bean也要修改一下。

    因为我使用的是jackson来进行json解析的,所以使用注解@JsonProperty来表示一下修改的json文件对应原来的java bean里面的属性,这样解析的时候就不会出错了。
    在这里插入图片描述

    经过上面的常规操作,
    我们的json文件大小减少到了1.04Mb,
    比最开始的原始数据2.13Mb,
    小了整整1.09Mb,

    压缩率为51.174%,压缩后体积为原来的48.826%

    已经算很给力了,但是这个json文件还是有1.04Mb啊,是否还可以进行压缩呢?答案是肯定的,我们下面介绍下使用算法对该json文件进行压缩。

    三、使用压缩算法进行压缩

    3.1 使用Deflater压缩json,Inflater解压json

    Deflater 是同时使用了LZ77算法与哈夫曼编码的一个无损数据压缩算法。

    我们可以使用 java 提供的 Deflater 和 Inflater 类对 json 进行压缩和解压缩,下面是工具类

    package com.oyp.sort.utils;
    

    import android.support.annotation.Nullable;
    import android.util.Base64;

    import java.io.ByteArrayOutputStream;
    import java.util.zip.DataFormatException;
    import java.util.zip.Deflater;
    import java.util.zip.Inflater;

    DeflaterUtils 压缩字符串
    /
    public class DeflaterUtils {
    /
    *

    压缩
    /
    public static String zipString(String unzipString{
    /
    *

    https://www.yiibai.com/javazip/javazip_deflater.html#article-start
    
    0 ~ 9 压缩等级 低到高
    
    public static final int BEST_COMPRESSION = 9;            最佳压缩的压缩级别。
    
    public static final int BEST_SPEED = 1;                  压缩级别最快的压缩。
    
    public static final int DEFAULT_COMPRESSION = -1;        默认压缩级别。
    
    public static final int DEFAULT_STRATEGY = 0;            默认压缩策略。
    
    public static final int DEFLATED = 8;                    压缩算法的压缩方法(目前唯一支持的压缩方法)。
    
    public static final int FILTERED = 1;                    压缩策略最适用于大部分数值较小且数据分布随机分布的数据。
    
    public static final int FULL_FLUSH = 3;                  压缩刷新模式,用于清除所有待处理的输出并重置拆卸器。
    
    public static final int HUFFMAN_ONLY = 2;                仅用于霍夫曼编码的压缩策略。
    
    public static final int NO_COMPRESSION = 0;              不压缩的压缩级别。
    
    public static final int NO_FLUSH = 0;                    用于实现最佳压缩结果的压缩刷新模式。
    
    public static final int SYNC_FLUSH = 2;                  用于清除所有未决输出的压缩刷新模式; 可能会降低某些压缩算法的压缩率。
    

    */
    //使用指定的压缩级别创建一个新的压缩器。
    Deflater deflater new Deflater(Deflater.BEST_COMPRESSION);
    //设置压缩输入数据。
    deflater.setInput(unzipString.getBytes());
    //当被调用时,表示压缩应该以输入缓冲区的当前内容结束。
    deflater.finish();

    final byte[] bytes new byte[256];
    ByteArrayOutputStream outputStream new ByteArrayOutputStream(256);

    while (!deflater.finished(){
    //压缩输入数据并用压缩数据填充指定的缓冲区。
    int length = deflater.deflate(bytes);
    outputStream.write(bytes0, length);
    }
    //关闭压缩器并丢弃任何未处理的输入。
    deflater.end();
    return Base64.encodeToString(outputStream.toByteArray(), Base64.NO_PADDING);
    }

    解压缩
    */
    @Nullable
    public static String unzipString(String zipString{
    byte[] decode = Base64.decode(zipString, Base64.NO_PADDING);
    //创建一个新的解压缩器 https://www.yiibai.com/javazip/javazip_inflater.html
    Inflater inflater new Inflater();
    //设置解压缩的输入数据。
    inflater.setInput(decode);

    final byte[] bytes new byte[256];
    ByteArrayOutputStream outputStream new ByteArrayOutputStream(256);
    try {
    //finished() 如果已到达压缩数据流的末尾,则返回true。
    while (!inflater.finished(){
    //将字节解压缩到指定的缓冲区中。
    int length = inflater.inflate(bytes);
    outputStream.write(bytes0, length);
    }