压缩算法进行字符串压缩
Deflater压缩,Inflater解压(较好)
import com.sun.istack.internal.Nullable;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.output.ByteArrayOutputStream;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
/**
* DeflaterUtils 压缩字符串
*/
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());
//当被调用时,表示压缩应该以输入缓冲区的当前内容结束。
deflater.finish();
final byte[] bytes = new byte[256];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(256);
while (!deflater.finished()) {
//压缩输入数据并用压缩数据填充指定的缓冲区。
int length = deflater.deflate(bytes);
outputStream.write(bytes, 0, length);
}
//关闭压缩器并丢弃任何未处理的输入。
deflater.end();
return Base64.encodeBase64String(outputStream.toByteArray());
}
/**
* 解压缩
*/
@Nullable
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[256];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(256);
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();
}
return outputStream.toString();
}
}
总结
- 压缩前的字节长度为:1825
- 压缩后的字节长度为:284
- 压缩率为63.73%,压缩后体积为原来的36.27%
- 5000字符长度压缩耗时20ms(较快)
压缩率和压缩前字节长度有一定关系,并不是随着字节长度线性增长。如:
5000字符长度,压缩后:2500左右
13000字符长度,压缩后:4000左右
Gzip压缩(还行)
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* GZip工具类
* zip压缩解压并使用Base64进行编码工具类
* 调用:
* 压缩
* GZipUtil.compress(str)
* 解压
* GZipUtil.uncompressToString(bytes)
*/
public class GzipUtil {
public static final Logger log = LoggerFactory.getLogger(GzipUtil.class);
/**
* 将字符串进行gzip压缩
*
* @param data
* @return
*/
public static String compress(String data) {
if (data == null || data.length() == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip;
try {
gzip = new GZIPOutputStream(out);
gzip.write(data.getBytes(StandardCharsets.UTF_8));
gzip.close();
} catch (IOException e) {
e.printStackTrace();
}
return Base64.encodeBase64String(out.toByteArray());
}
/**
* 解压
* @param data
* @return
*/
public static String uncompress(String data) {
if (TextUtils.isEmpty(data)) {
return null;
}
byte[] decode = Base64.decodeBase64(data);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(decode);
GZIPInputStream gzipStream = null;
try {
gzipStream = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = gzipStream.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
} catch (IOException e) {
log.error("e = ", e);
} finally {
try {
out.close();
if (gzipStream != null) {
gzipStream.close();
}
} catch (IOException e) {
log.error("e = ", e);
}
}
return new String(out.toByteArray(), StandardCharsets.UTF_8);
}
}
总结
- 压缩前的字节长度为:1825
- 压缩后的字节长度为:307
- 压缩率为62.04%,压缩后体积为原来的37.95%
- 5000字符长度压缩耗时167ms(较慢)
压缩率与字符长度关系同上