数据压缩解压

分享一个数据压缩解压工具方法,这个压缩出来长度是不确定的

package com.picccdyf.sff.inter.infrastructure.util;


import com.picccdyf.sff.inter.infrastructure.common.Constants;
import cwzx.cdyf.common.exception.PiccCommonException;
import cwzx.cdyf.common.util.StringUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * description:数据压缩解压工具方法
 *
 * @author zhilong.xu
 * @since 2020/10/26 16:49
 */
public class CompressUtil {
    //BYTEONE和BYTETWO两个字节,一起构成一个UTF8中有,但ISO8859-1中没有的字符
    private static final byte BYTEONE = (byte)-60;
    private static final byte BYTETWO = (byte)-128;
    private static final String UTF8 = "utf8";
    private static final String ISO88591 = "ISO-8859-1";

    /**
     * description:将字符串压缩
     *
     * @param str 入参字符串
     * @return String 压缩后字符串
     * @author zhilong.xu
     * @since 2020/10/26 10:04
     */
    public static String compress(String str) throws IOException {
        //字符串判空
        if (StringUtil.isNull(str)) {
            return "";
        }
        //对字符串进行压缩
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        try{
            gzip.write(str.getBytes(UTF8));
        } catch (Exception e){
            throw new PiccCommonException("压缩失败");
        } finally {
            gzip.close();
        }
        //将压缩后的ISO-8859-1编码的字节数组转换成字符串,再将字符串转换成utf8格式的字节数组。
        String result = out.toString(ISO88591);
        byte[] utf8s = result.getBytes(UTF8);
        //将utf8字节数组的0x00单字节替换成-60,-128的双字节。因为postgresql数据库utf8类型的varchar不能存入0x00字节,所以需要进行替换。
        int size = utf8s.length;
        List<Byte> list = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            if (utf8s[i] == 0x00) {
                list.add(BYTEONE);
                list.add(BYTETWO);
            } else {
                list.add(utf8s[i]);
            }
        }
        //将替换后utf8编码的list类型转换成byte[]类型
        byte[] utf8snew = new byte[list.size()];
        for (int i = 0; i < list.size(); i++) {
            utf8snew[i] = list.get(i);
        }
        //将替换后的utf8字节数组转换成字符串
        return new String(utf8snew, UTF8);
    }


    /**
     * description:将字符串解压
     *
     * @param str 入参字符串
     * @return String 解压后字符串
     * @author zhilong.xu
     * @since 2020/10/26 10:04
     */
    public static String unCompress(String str) throws IOException {
        if(StringUtil.isNull(str)){
            return "";
        }
        //将字符串转换成utf8字节流数组
        byte[] utf8s = str.getBytes(UTF8);
        //将utf8字节数组的-60,-128双字节替换成0x00的单字节
        List<Byte> list = new ArrayList();
        for (int i = 0; i < utf8s.length; i++) {
            if (utf8s[i] == BYTEONE) {
                if (utf8s[++i] == BYTETWO) {
                    list.add((byte) 0x00);
                }
            } else {
                list.add(utf8s[i]);
            }
        }
        //将list转换成byte[]
        byte[] utf8snew = new byte[list.size()];
        for (int i = 0; i < list.size(); i++) {
            utf8snew[i] = list.get(i);
        }
        //对utf8字节数组进行解码,得到字符串
        String str1 = new String(utf8snew, UTF8);
        if (StringUtil.isNull(str1)) {
            return "";
        }
        //将字符串还原成压缩后的iso-8859-1字节流,再进行解压缩。
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(str1.getBytes(ISO88591));
        GZIPInputStream gzip = new GZIPInputStream(in);
        byte[] buffer = new byte[Constants.NUMBER.NUM256];
        int n = 0;
        while ((n = gzip.read(buffer)) >= 0) {
            out.write(buffer, 0, n);
        }
        out.close();
        gzip.close();
        //得到解压缩后的iso-8859-1字节流,然后转换成字符串
        return out.toString(UTF8);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值