压缩函数
3 分钟 9301 字 |
压缩函数
利用压缩算法对字符串进行压缩,常用的函数有Deflater&Inflater,gzip,zip等
压缩效率:Deflater > gzip > zip
Deflater
Deflater压缩,Inflater解压(较好)
public class DeflaterUtils {
/**
* 压缩
*/
public static String zipString(String unzipString) {
/*
* https://www.yiibai.com/javazip/javazip_deflater.html#article-start
* 0 ~ 9 压缩等级 低到高
* public static final int BEST_COMPRESSION = 9; 最佳压缩的压缩级别。
* public static final int BEST_SPEED = 1; 压缩级别最快的压缩。
* public static final int DEFAULT_COMPRESSION = -1; 默认压缩级别。
* public static final int DEFAULT_STRATEGY = 0; 默认压缩策略。
* public static final int DEFLATED = 8; 压缩算法的压缩方法(目前唯一支持的压缩方法)。
* public static final int FILTERED = 1; 压缩策略最适用于大部分数值较小且数据分布随机分布的数据。
* public static final int FULL_FLUSH = 3; 压缩刷新模式,用于清除所有待处理的输出并重置拆卸器。
* public static final int HUFFMAN_ONLY = 2; 仅用于霍夫曼编码的压缩策略。
* public static final int NO_COMPRESSION = 0; 不压缩的压缩级别。
* public static final int NO_FLUSH = 0; 用于实现最佳压缩结果的压缩刷新模式。
* public static final int SYNC_FLUSH = 2; 用于清除所有未决输出的压缩刷新模式; 可能会降低某些压缩算法的压缩率。
*/
//使用指定的压缩级别创建一个新的压缩器。
Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
//设置压缩输入数据。
deflater.setInput(unzipString.getBytes(StandardCharsets.UTF_8));
//当被调用时,表示压缩应该以输入缓冲区的当前内容结束。
deflater.finish();
final byte[] bytes = new byte[512];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(512);
while (!deflater.finished()) {
//压缩输入数据并用压缩数据填充指定的缓冲区。
int length = deflater.deflate(bytes);
outputStream.write(bytes, 0, length);
}
//关闭压缩器并丢弃任何未处理的输入。
deflater.end();
return Base64.encodeBase64String(outputStream.toByteArray());
//处理回车符
// return zipString.replaceAll("[\r\n]", "");
}
/**
* 解压缩
*/
public static String unzipString(String zipString) {
byte[] decode = Base64.decodeBase64(zipString);
//创建一个新的解压缩器 https://www.yiibai.com/javazip/javazip_inflater.html
Inflater inflater = new Inflater();
//设置解压缩的输入数据。
inflater.setInput(decode);
final byte[] bytes = new byte[512];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(512);
try {
//finished() 如果已到达压缩数据流的末尾,则返回true。
while (!inflater.finished()) {
//将字节解压缩到指定的缓冲区中。
int length = inflater.inflate(bytes);
outputStream.write(bytes, 0, length);
}
} catch (DataFormatException e) {
e.printStackTrace();
return null;
} finally {
//关闭解压缩器并丢弃任何未处理的输入。
inflater.end();
}
try {
return outputStream.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
压缩率为63.73%,压缩后体积为原来的36.27%; 5000字符长度压缩耗时5ms(较快)
Gzip
public class GzipUtils {
private static final String GZIP_ENCODE_UTF_8 = "UTF-8";
private static final String GZIP_ENCODE_ISO_8859_1 = "ISO-8859-1";
private static final int BYTE_NUM = 25600;
/**
* 压缩方法
* @param str
* @return
* @throws IOException
*/
public static String compress(String str) throws IOException {
return new String(compressData(str, GZIP_ENCODE_UTF_8), GZIP_ENCODE_ISO_8859_1);
}
/**
* 压缩具体实现
* @param str
* @param encoding
* @return
*/
private static byte[] compressData(String str, String encoding) {
if (str == null || str.length() == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip;
try {
gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes(encoding));
gzip.close();
} catch (IOException e) {
System.out.println("压缩数据失败:" + e.getMessage());
}
return out.toByteArray();
}
/**
* 解压缩方法
* @param byteStr
* @return
*/
public static String decompressToStr(String byteStr) {
byte[] bytes;
try {
bytes = byteStr.getBytes(GZIP_ENCODE_ISO_8859_1);
return decompressDataToStr(bytes, GZIP_ENCODE_UTF_8);
} catch (UnsupportedEncodingException e) {
System.out.println("解压缩数据转码失败:" + e.getMessage());
}
return null;
}
/**
* 解压缩具体实现
* @param bytes
* @param encoding
* @return
*/
private static String decompressDataToStr(byte[] bytes, String encoding) {
if (bytes == null || bytes.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
try {
GZIPInputStream ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[BYTE_NUM];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
return out.toString(encoding);
} catch (IOException e) {
System.out.println("解压缩数据失败:" + e.getMessage());
}
return null;
}
}
zip
public class ZipUtils {
/**
* 使用zip进行解压缩
*
* @param compressedStr 压缩后的文本
* @return 解压后的字符串
*/
public static final String unzip(String compressedStr) {
if (compressedStr == null) {
return null;
}
ByteArrayOutputStream out = null;
ByteArrayInputStream in = null;
ZipInputStream zin = null;
String decompressed = null;
try {
byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
out = new ByteArrayOutputStream();
in = new ByteArrayInputStream(compressed);
zin = new ZipInputStream(in);
zin.getNextEntry();
byte[] buffer = new byte[1024];
int offset = -1;
while ((offset = zin.read(buffer)) != -1) {
out.write(buffer, 0, offset);
}
decompressed = out.toString();
} catch (IOException e) {
decompressed = null;
} finally {
if (zin != null) {
try {
zin.close();
} catch (IOException e) {
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
}
}
}
return decompressed;
}
}
压缩率为62.04%,压缩后体积为原来的37.95%; 5000字符长度压缩耗时20ms(较慢)
参考
[ 1 ] https://www.cnblogs.com/zohnn/p/12899931.html
[ 2 ] https://cloud.tencent.com/developer/article/1673594
~ ~ The End ~ ~
分类标签:技术,springboot,java
文章标题:压缩函数
文章链接:http://120.46.217.131:82/archives/48/
最后编辑:2023 年 3 月 7 日 16:11 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
文章标题:压缩函数
文章链接:http://120.46.217.131:82/archives/48/
最后编辑:2023 年 3 月 7 日 16:11 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)