GZIPOutputStream GZIPInputStream 数据压缩解压

news2025/1/31 11:09:26

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

数据压缩&解压

  • 前言
  • 一、最终走上了压缩的路 GZIPOutputStream
  • 二、收到数据进行解压 GZIPInputStream
  • 三、测试Demo
  • 四、验证结果
  • 总结


前言

最近接手了一批性能优化…
遇到这样一个接口:已经把能优化的部分都优化了(包括业务逻辑批处理、数据预处理、数据缓存、减少查表字段、加表索引等)。

但是,这个接口里有个外部调用会去查询3000+数据,得到的数据大小约为1.5M,耗时:2s
外部系统接口执行时间为:0.8s
那么就意味着...数据传输消耗了:1s+

解决方法:
外部系统将出参:压缩
自己系统将得到数据:解压
从而减少数据传输的时间

其他方面:减少出参的冗余字段

一、最终走上了压缩的路 GZIPOutputStream

将json字符串压缩,再加密(保证安全性)

    public static String getCompressionStr(String jsonStr) throws Exception {
        
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gos = new GZIPOutputStream(out);

        gos.write(jsonStr.getBytes(StandardCharsets.UTF_8));
        gos.close();

        byte[] encodeBytes = Base64.getEncoder().encode(out.toByteArray());
        return new String(encodeBytes);
   

二、收到数据进行解压 GZIPInputStream

将收到的字符串进行解密,再解压

    public static String getDecompressionStr(String compressionStr) throws Exception {
        byte[] decodedBytes = Base64.getDecoder().decode(compressionStr);
        
        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(decodedBytes));
        BufferedReader bf = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8));

        StringBuilder outStr = new StringBuilder();
        String line;

        while ((line = bf.readLine()) != null) {
            outStr.append(line);
        }

        return StringEscapeUtils.unescapeJava(outStr.toString());
    }

三、测试Demo

**** 重要提示 *******
1:验证的时候,日志记得分开打印。日志很大,不然不好查看日志数据
2:调整idea的 setting -> Editor -> General -> Console
Override console cycle buffer size 调整为10240

public class Demo {

    public static void main(String[] args) {
        String jsonStr = getJsonStr();
        System.out.println(jsonStr);
        
        try {
            String compressionStr = getCompressionStr(jsonStr);
//            System.out.println(compressionStr);

            String decompressionStr = getDecompressionStr(compressionStr);
//            System.out.println(decompressionStr);

            List<User> users = JSONArray.parseArray(decompressionStr, User.class);
            System.out.println(users.get(100));
            System.out.println(users.get(100).getUserId());
            System.out.println(users.get(100).getName());
            System.out.println(users.get(100).getAddress());


        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
	
	/**
	 * 随便创建10000个对象,userId,name,address
	 **/
    public static String getJsonStr() {
        List<User> users = new ArrayList<>();
        String address = "让我感到为难的 是挣扎的自由\n" +
                "分别总是在九月 回忆是思念的愁\n" +
                "深秋嫩绿的垂柳 亲吻着我额头\n" +
                "在那座阴雨的小城里 我从未忘记你\n" +
                "成都 带不走的 只有你\n" +
                "和我在成都的街头走一走 喔…\n" +
                "直到所有的灯都熄灭了也不停留";
        for (int i = 0; i < 10000; i++) {
            users.add(new User((long) (i + 1), "张三" + (i + 1), address));
        }
        return JSONArray.toJSONString(users);
    }

四、验证结果

在这里插入图片描述
1:10000个对象的大小为 3328KB
2:压缩后的大小为 80KB
3:解压后的大小为 3328KB
4:解压后数据可转为对象(支持嵌套对象),正常使用

            List<User> users = JSONArray.parseArray(decompressionStr, User.class);

            System.out.println(users.get(100));
            System.out.println(users.get(100).getUserId());
            System.out.println(users.get(100).getName());
            System.out.println(users.get(100).getAddress());
    对应的输出结果为:
    
User(userId=101, name=张三101, address=让我感到为难的 是挣扎的自由
分别总是在九月 回忆是思念的愁
深秋嫩绿的垂柳 亲吻着我额头
在那座阴雨的小城里 我从未忘记你
成都 带不走的 只有你
和我在成都的街头走一走 喔…
直到所有的灯都熄灭了也不停留)

101

张三101

让我感到为难的 是挣扎的自由
分别总是在九月 回忆是思念的愁
深秋嫩绿的垂柳 亲吻着我额头
在那座阴雨的小城里 我从未忘记你
成都 带不走的 只有你
和我在成都的街头走一走 喔…
直到所有的灯都熄灭了也不停留
            

总结

性能优化是真的心累。
特别是产品经理的沙雕设计(一次性拿3000条数据就不合理,为了强行实现功能)
最后说下优化的结果:产线上12s的接口,最终降低至2s

另外说明下:
文章内除了StringEscapeUtils以外,仅用到了jdk自带的库

但是在lang3里StringEscapeUtils已经Deprecated了。可以换成common-text
import org.apache.commons.text.StringEscapeUtils;
//import org.apache.commons.lang3.StringEscapeUtils;

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.10.0</version>
    </dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/433482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全注解下的SpringIoc

Spring架构中的核心理念就是IOC和AOP&#xff0c;可以说&#xff0c;Spring的强大离不开这两大特性。 因为spring boot推荐采用注解开发&#xff0c;所以文中主要介绍基于注解的Spring Ioc。 IoC容器简介 Spring IoC 容器是个管理 Bean&#xff08;在Spring 中把每个需要管理…

VMware vCenter Server 8.0U1 发布 - 集中式管理 vSphere 环境

请访问原文链接&#xff1a;VMware vCenter Server 8.0U1 - 集中式管理 vSphere 环境&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023-04-18, VMware vSphere 8.0U1 发布。 详见&#xff1a;VMware vSphere 8 Update 1 新…

单片机的实例——28BYJ48步进电机

整体过程 准备资料1&#xff0c;步进电机内部结构示意图2&#xff0c;步进电机命名3&#xff0c;实际结构的转速比4&#xff0c;数值的含义5&#xff0c;实际内部主动轮结构分析实际内部机构及接线定子部分转子部分 定子和转子磁极的工作分析 6&#xff0c;工作时序7&#xff0…

机器学习 day06(向量化应用于多元线性回归的梯度下降算法,正规方程)

向量化多元线性回归&#xff0c;及梯度下降算法 将W₁&#xff0c;…&#xff0c;Wn写成向量W&#xff0c;将X₁&#xff0c;…&#xff0c;Xn写成向量X&#xff0c;而b还是之前的b注意&#xff1a;在多元线性回归的梯度下降算法中&#xff0c;Wj是指从W₁到Wn中的某一项&…

堆排序及top-k问题

堆排序及top-k问题 堆排序建堆向上调整建堆向下建堆 堆排序 top-k问题&#xff0c;建堆的应用 堆排序 堆排序&#xff0c;听名字就是要对堆进行排序&#xff0c;但当我们是无序数据时&#xff0c;首先我们就需要建立一个堆 建堆 这里让我们来回忆一下前面的堆&#xff0c;改…

Springboot基础学习之(二十三):实现定时任务

定时任务&#xff1a;在开发过程中是经常能够使用到的&#xff1a;定时发布邮件等等 先了解一下什么时cron表达式&#xff1f; 它是定义执行任务时间的一种时间表达式&#xff0c;使用方法 Scheduled(cron "0/2 * * * * ? ")&#xff0c;这里代码的含义是每两秒执行…

适用于 Windows 的 5 个最好的 PDF 转换器应用程序

由于稳定性、高分辨率、高安全性、易于传输等特点&#xff0c;PDF已经成为我们日常工作中最常用的格式。我们在享受PDF带来便利的同时&#xff0c;也发现PDF带来了一些不便&#xff0c;其中最大的问题就是PDF内容的编辑难度。同时&#xff0c;并不是所有的文件都是PDF格式的&am…

【redis】Redis为什么能抗住10万并发?

文章目录1. Redis简介2. 内存操作3. 丰富的对象类型4. 高效的数据结构5. 单线程模型6. 多路IO复用模型7. 总结1. Redis简介 Redis是一个开源的&#xff0c;基于内存的&#xff0c;高性能的键值型数据库。它支持多种数据结构&#xff0c;包含五种基本类型 String&#xff08;字…

搭建vue3项目+按需引入element-ui框架组件

场景&#xff1a;使用vue create脚手架快速搭建vue的项目 前提&#xff1a;需要安装node.js和cnpm以及yarn 并且cnpm需要设置为淘宝镜像&#xff0c;cnpm和yarn安装教程网上很多可以自行搜索 1.使用dos命令安装vue-cli脚手架 //这个是从镜像源下载 cnpm install -g vue/cli 查…

设计模式简述

设计模式(简述) 设计模式的分类 ​ 根据目的可以分为创建型、结构性和行为型三类&#xff1a; 创建型模型&#xff1a;创建对象结构性模型&#xff1a;处理类或对象的组合行为型模式&#xff1a;用于描述对类或对象怎样交互和怎么分派职责 ​ 根据范围可以分为类模式和对象…

13.基于双层优化的电动汽车日前-实时两阶段市场竞标

MATLAB代码&#xff1a;基于双层优化的电动汽车日前-实时两阶段市场竞标 关键词&#xff1a;日前-实时市场竞标 电动汽车 双层优化 编程语言&#xff1a;MATLAB平台 内容简介&#xff1a;代码主要做的是电动汽车充电站市场竞标策略&#xff0c;采用双层优化模型对电动汽车…

Redis缓存穿透、击穿、雪崩面试题详解

缓存穿透 问题&#xff1a; 指的是客户端请求的数据在缓存中找不到&#xff0c;数据库中也没有存储&#xff0c;客户端还不断的发起请求。这样每次都无法在数据库查询到&#xff0c;缓存中永远没有这个数据。 ​ 这样的话&#xff0c;客户端一直去访问&#xff0c;会给后端数据…

【观察】解读新一代戴尔AMD服务器:场景优化为先,筑牢数字化底座

毫无疑问&#xff0c;今天算力就是生产力已成为业界共识&#xff0c;特别是算力作为数字经济时代的关键生产力要素&#xff0c;更成为了挖掘数据要素价值&#xff0c;推动数字经济发展的核心支撑力和驱动力。 在此过程中&#xff0c;由算力驱动的数字经济除了以信息产业这一独立…

老胡的周刊(第087期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 Auto-GPT[2] Auto-GPT 是一个实验性的开源应…

极简sklearn-使用决策树预测泰坦尼克号幸存者

泰坦尼克号幸存者数据集是kaggle竞赛中入门级的数据集&#xff0c;今天我们就来用决策树来预测下哪些人会成为幸存者。 数据集下载地址: https://download.csdn.net/download/ting4937/87630361 数据集中包含两个csv文件&#xff0c;data为训练用数据,test为测试集。 探索数据…

通过HBuilderX运行uniapp到微信者开发工具

目录 一、安装开发工具 二、配置运行微信开发者工具 三、异常处理 1.[微信小程序开发者工具] ? Enable IDE Service (y/N) [27D[27C 2. [error] Error: Fail to open IDE 3.[app.json 文件内容错误] app.json: 在项目根目录未找到 app.json 一、安装开发工具 安装HBuil…

如今的就业环境下,怎样才能跻身于高收入的IC行业?

看到不少人失业找工作&#xff0c;其实现在不光是大学生难找工作&#xff0c;在职的人工作也不怎么开心。 要么累&#xff0c;要么没前途。 要么又累又没前途。 总的占个啥吧&#xff0c;现在大家面临的问题就是工作时间越来越久&#xff0c;人际关系也搞得很压抑&#xff0…

初识linux之线程同步与生产者消费者模型

目录 一、线程同步的概念 1. 饥饿状态 2. 同步的概念 二、生产者消费者模型 1. 生产者消费者模型基本概念 2. 生产者、消费者之间的关系 2.1 消费者与消费者的关系 2.2 生产者和生产者的关系 2.3 生产者和消费者的关系 3. “321”原则 4. 消费者与生产者模型的特点 …

C++数据结构:STL

数据结构和算法简介 数据结构 数据结构是相互间存在特定关系的数据的集合&#xff0c;分为逻辑结构和物理结构。 逻辑结构 反映数据元素之间的逻辑关系的数据结构&#xff0c;其中的逻辑关系是指数据元素之间的前后件关系&#xff0c;而与他们在计算机中的存储位置无关 集…

类加载器详解(重点)之双亲委派

回顾一下类加载过程 开始介绍类加载器和双亲委派模型之前&#xff0c;简单回顾一下类加载过程。 类加载过程&#xff1a;加载->连接->初始化。连接过程又可分为三步&#xff1a;验证->准备->解析。 加载是类加载过程的第一步&#xff0c;主要完成下面 3 件事情…