Java 字符串压缩与解压的开发记录

 更新时间:2022年06月09日 11:17:28   作者:你好像很好吃a  
这篇文章主要介绍了Java 字符串压缩与解压的开发记录,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

1、场景:

由于数据库字段长度有限,并且不能随意的修改数据库字段的配置,数据库的某个字段设置的长度可能在设置初期是满足需求的,后期由于业务变更或业务量增大导致该字段存储的数据增长,落库时可能因为该字段数据长度过长导致落库失败,基于这种场景我们就有必要进行字符串的压缩,然后再进行落库,而落库后取出数据使用时再进行解压即可。

2、CompressUtil类:

使用Java8中的gzip来进行实现

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
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;
/**
 * 压缩String的工具类
 */
@Slf4j
public class CompressUtil {
    /**
     * 使用gzip压缩字符串
     * @param str 要压缩的字符串
     * @return 压缩后的字符串
     */
    public static String compress(String str) {
        if (str == null || str.length() <= 0) {
            return str;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (GZIPOutputStream gzip = new GZIPOutputStream(out)) {
            gzip.write(str.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error("字符串压缩失败str:{},错误信息:{}", str, e.getMessage());
            throw new RuntimeException("字符串压缩失败");
        }
        return Base64.encodeBase64String(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 in;
        GZIPInputStream gzip = null;
        byte[] compressed;
        String decompressed;
        try {
            compressed = Base64.decodeBase64(compressedStr);
            in = new ByteArrayInputStream(compressed);
            gzip = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int offset;
            while ((offset = gzip.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString(StandardCharsets.UTF_8.name());
        } catch (IOException e) {
            log.error("字符串解压失败compressedStr:{},错误信息:{}", compressedStr, e.getMessage());
            throw new RuntimeException("字符串解压失败");
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException ignored) {
                }
            }
            try {
                out.close();
            } catch (IOException ignored) {
            }
        }
        return decompressed;
    }
}

3、注意点:

1)CompressUtil在压缩过程和解压过程使用统一字符集,防止压缩和解压过程因为字符集不同导致结果与实际预期不符;

2)在web项目中,服务器端将加密后的字符串返回给前端,前端再通过ajax请求将加密字符串发送给服务器端处理的时候,在http传输过程中会改变加密字符串的内容,导致服务器解压压缩字符串发生异常;

而CompressUtil压缩和解压过程中使用Base64.encodeBase64String和Base64.decodeBase64进行编码和解码,可以完全解决上述问题。

3)压缩/解压失败怎么处理?
通过CompressUtil工具类可以看出,如果压缩或解压失败,过程发生异常,则会抛出一个运行时异常给调用方,方便调用方及时感知并处理;

具体如何处理要看具体的业务场景,我这边是在MQ消费者中调用,在MQ中统一捕获异常,所以如果压缩失败会进行重试,如果重试多次依然失败,我这边会进行报警打印日志,内部人会去处理。

4、单元测试:

import org.junit.Test;
public class CompressUtilTest {
    @Test
    public void test1() {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0;i < 100000;i++) {
            stringBuilder.append("1");
        }
        System.out.println(stringBuilder.toString().length());
        String compress = CompressUtil.compress(stringBuilder.toString());
        System.out.println("compress="+compress);
        System.out.println(compress.length());
        String uncompress = CompressUtil.uncompress(compress);
        System.out.println(uncompress.length());
        System.out.println("uncompress=" + uncompress);
    }
}

测试1:100000压缩以后为180,解压后也可以正常返回原字符串

测试2:把压缩字符串长度改为1000再试一次,压缩后长度为40

压缩比例还是很高的,亲测可用!!!

到此这篇关于Java 字符串压缩与解压的开发记录的文章就介绍到这了,更多相关Java 字符串压缩 解压内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • emoji表情与unicode编码互转的实现(JS,JAVA,C#)

    emoji表情与unicode编码互转的实现(JS,JAVA,C#)

    这篇文章主要介绍了emoji表情与unicode编码互转的实现(JS,JAVA,C#),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java springboot Mongodb增删改查代码实例

    Java springboot Mongodb增删改查代码实例

    这篇文章主要介绍了Java springboot Mongodb增删改查代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 理解Java注解及Spring的@Autowired是如何实现的

    理解Java注解及Spring的@Autowired是如何实现的

    今天通过本文带领大家学习注解的基础知识,学习Spring的@Autowired是怎么实现的,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-07-07
  • java web中 HttpClient模拟浏览器登录后发起请求

    java web中 HttpClient模拟浏览器登录后发起请求

    这篇文章主要介绍了java web中 HttpClient模拟浏览器登录后发起请求的相关资料,需要的朋友可以参考下
    2017-05-05
  • SpringBoot2整合Ehcache组件实现轻量级缓存管理

    SpringBoot2整合Ehcache组件实现轻量级缓存管理

    EhCache是一个纯Java的进程内缓存框架,具有快速、上手简单等特点,是Hibernate中默认的缓存提供方。本文讲述下SpringBoot2 整合Ehcache组件的步骤
    2021-06-06
  • Springboot集成JSR303参数校验的方法实现

    Springboot集成JSR303参数校验的方法实现

    这篇文章主要介绍了Springboot集成JSR303参数校验的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Java接口统一样式返回模板简介

    Java接口统一样式返回模板简介

    这篇文章主要介绍了Java接口统一样式返回模板简介,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • [Spring MVC] -简单表单提交实例

    [Spring MVC] -简单表单提交实例

    本篇文章主要介绍了[Spring MVC] -简单表单提交实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。
    2016-12-12
  • 一篇文章带你入门java网络编程

    一篇文章带你入门java网络编程

    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。本文介绍了一些网络编程基础的概念,并用Java来实现TCP和UDP的Socket的编程,来让读者更好的了解其原理
    2021-08-08
  • JAVA生成八位不重复随机数最快的方法总结(省时间省空间)

    JAVA生成八位不重复随机数最快的方法总结(省时间省空间)

    随机数在实际中使用很广泛,比如要随即生成一个固定长度的字符串、数字,这篇文章主要给大家介绍了关于JAVA生成八位不重复随机数最快的方法,文中介绍的方法省时间省空间,需要的朋友可以参考下
    2024-03-03

最新评论

?


http://www.vxiaotou.com