GZIP压缩字符串2

简介: GZIP压缩字符串2

今天看了一个压缩字符串的方式,直接使用的Java8的API实现的。

Http中有三种压缩:

  • Zlib:常见类型有zip、rar和7z等。非常流行的文件压缩算法.在Linux 平台应用十分广泛
  • Deflate:更高的压缩率,7-zip就是实现的它,它还可以对gzip、PNG、MNG甚至Zip文件进行再次压缩从而得到比zlib压缩更小的大小.
  • Gzip:一种无损压缩算法,其基础为Deflate,两者差不多。


我们在Http请求头中可以看到支持的压缩算法,支持哪种就会显示哪种:

   Deflate是LZ77与哈弗曼编码的一个组合体。

   基本原理是:对于要压缩的文件,首先使用LZ77算法的一个变种进行压缩,对得到的结果再使用哈夫曼编码(根据情况,使用静态哈弗曼编码或动态哈夫曼编码)的方法进行压缩。

那么什么是LZ77呢?

   LZ77严格意义上来说不是一种算法,而是一种编码理论。它的核心思路是如果一个串中有两个重复的串,那么只需要知道后面的串与前面串重复的长度和后面串起始字符与前面串起始字符相对于起始位置的距离。

   什么玩意,不好理解哈。

   来举个例子:

   比如字符串“不要啊不要啊停”,可以看到重复字符串有两个:“不要啊”

通过LZ77算法可压缩为“不要啊(4,3)停”,其中4表示重复的字符串起始字符(也就是第二个“不”)到第一个重复字符串起始字符(也就是第一个“不”)的距离,3表示重复字符串的长度。

   由此可见,对要压缩的字符串是有要求的,重复度越高的字符串,压缩效果是越好!我通过生成UUID字符串测试了,1000个字符它给我压缩成了950个,啊哈哈,这压了个毛!

那么哈夫曼编码是什么呢?

   哈夫曼编码是数据结构课程中一种常见的算法。哈夫曼编码使用变长编码表对源符号进行编码,变长编码表通过一种评估来源符号出现概率的方法得到,出现概率较高的字母使用较短的编码,反之出现概率低的使用较长的编码,这样使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

   好吧,这个我也不明白,数据结构中有讲,但是我没学。。。

下面是工具类代码:















































































































package com.xing.parent.utils;
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.nio.charset.StandardCharsets;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;
/** *  字符串压缩与解压缩 * @author xinghua */public class CompressUtils {
    /**     * 使用gzip压缩字符串     * @param str 要压缩的字符串     * @return str     */    public static String compress(String str) {if (str == null || str.length() == 0) {return str;        }        ByteArrayOutputStream out = new ByteArrayOutputStream();        GZIPOutputStream gzip = null;try {            gzip = new GZIPOutputStream(out);            gzip.write(str.getBytes(StandardCharsets.UTF_8));        }catch (Exception e) {            e.printStackTrace();return str;        }finally {if (gzip != null) {try {                    gzip.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }return new sun.misc.BASE64Encoder().encode(out.toByteArray());    }
    /**     * 使用gzip解压缩     * @param compressedStr 要解压缩的字符串     * @return 解压后的字符串     */    public static String unCompress(String compressedStr) {if (compressedStr == null || compressedStr.length() == 0) {return compressedStr;        }        ByteArrayOutputStream out = new ByteArrayOutputStream();        ByteArrayInputStream inputStream = null;        GZIPInputStream gzipInputStream = null;        byte[] compressed;        String decompressed;try {            compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);            inputStream = new ByteArrayInputStream(compressed);            gzipInputStream = new GZIPInputStream(inputStream);            byte[] buffer = new byte[1024];            int offset = -1;while ((offset = gzipInputStream.read(buffer)) != -1) {                out.write(buffer, 0, offset);            }            decompressed = out.toString();        } catch (IOException e) {            e.printStackTrace();return compressedStr;        } finally {if (gzipInputStream != null) {try {                    gzipInputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }if (inputStream != null) {try {                    inputStream.close();                } catch (IOException e) {                    e.printStackTrace();                }            }try {                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }return decompressed;    }
    public static void main(String[] args) {for(int i=0;i<10;i++){//            String str1 = CommonUtil.getRandomStr(1000);            String str1 = "我自己的报文,你自己整一个";            System.out.println("压缩前大小:"+str1.length());            long t1 = System.currentTimeMillis();            String compress = CompressUtils.compress(str1);            System.out.println("压缩后大小:"+compress.length()+"|耗时:"+(System.currentTimeMillis()-t1)+"ms->");            long t2 = System.currentTimeMillis();            String unCompress = CompressUtils.unCompress(compress);            System.out.println("解压后大小:"+unCompress.length()+"|耗时:"+(System.currentTimeMillis()-t2)+"ms->");            System.out.println("对比压缩前后字符串:"+unCompress.equals(str1));        }    }}

结果:

   我们的一个单个请求报文有17K,压缩后就可以剩下5K,耗时也在可接受范围,不错!

   今天学到了一个压缩算法,工作中还学到了netty通信的水位问题。

   按鼠标手指都磨起泡了。。。

   五一劳动节快乐!


END

目录
相关文章
|
JSON API 数据格式
LangChain Agent:赋予 LLM 行动力的神秘力量
LangChain Agent 是什么?有什么用?基本原理是什么?那么多 Agent 类型在实际开发中又该如何选择?
1158 8
LangChain Agent:赋予 LLM 行动力的神秘力量
|
消息中间件 架构师 Java
史上最细最强大的RocketMQ实现分布式事务解决方案教程|Java 开发实战(上)
史上最细最强大的RocketMQ实现分布式事务解决方案教程|Java 开发实战
1110 0
史上最细最强大的RocketMQ实现分布式事务解决方案教程|Java 开发实战(上)
|
数据安全/隐私保护 Python
解决CondaHTTPError:HTTP 000 CONNECTION FAILED for url<https://mirrors.tuna.tsinghua.edu.cn/anaconda***
今天做项目的时候,Python导入一个包一直有各类问题,而后最终锁定问题是CondaHTTPError:HTTP 000 CONNECTION FAILED for url<https://mirrors.tuna.tsinghua.edu.cn/anaconda*** 这就是清华的源出问题了,配置没配对。
解决CondaHTTPError:HTTP 000 CONNECTION FAILED for url<https://mirrors.tuna.tsinghua.edu.cn/anaconda***
|
数据采集 机器学习/深度学习 PyTorch
Pytorch学习笔记(5):torch.nn---网络层介绍(卷积层、池化层、线性层、激活函数层)
Pytorch学习笔记(5):torch.nn---网络层介绍(卷积层、池化层、线性层、激活函数层)
1830 0
Pytorch学习笔记(5):torch.nn---网络层介绍(卷积层、池化层、线性层、激活函数层)
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
557 8
|
缓存 前端开发 JavaScript
优化前端性能的10个实用技巧
提高网站或应用程序的性能是前端开发中至关重要的一部分。本文将介绍10个实用的技巧,帮助前端开发人员优化其项目的性能,包括减少HTTP请求、使用CDN加速、压缩和合并文件、优化图片等方面的技术手段,以提升用户体验和网站加载速度。
python并发执行request请求
选择哪种并发方式取决于我们的具体需求。对于I/O密集型任务,多线程或异步I/O通常是更好的选择;对于CPU密集型任务,多进程可能是更好的选择。此外,异步I/O通常比多线程具有更好的性能,特别是在高并发的网络应用中。
|
存储 数据处理 索引
数据类型转换:int()、str()、float()
在Python中,数据类型转换是一项基础且重要的操作
|
消息中间件 缓存 负载均衡
【Kafka】Kafka 消息的消费模式
【4月更文挑战第5天】【Kafka】Kafka 消息的消费模式
|
Shell 网络安全 开发工具
配置SSH时候,Permission denied问题解决方法
配置SSH时候,Permission denied问题解决方法
1047 4