分享一个数据压缩解压工具方法,这个压缩出来长度是不确定的
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);
}
}