总第573篇
2023年 第025篇
1 前言
2 数据压缩技术
20世纪50~80年代,香农创立信息论,为数据压缩技术奠定了理论基础。期间出现多种经典算法,如 Huffman 编码、LZ 系列编码等。 1989年,推出文件归档软件 PKZIP(zip 前身),并公开文件归档格式 zip 及其使用的数据压缩算法 deflate(Huffman 与 LZ77 的组合算法)的所有技术参数。 1990年, 小组基于公开的 deflate 算法编写了可移植的、免费的、开源实现 zip 和 unzip,极大地扩展了 .zip 格式的使用。 1992年,Info-ZIP 小组基于 zip 的 deflate 算法代码,推出了文件压缩工具 gzip(GUN zip),用于替代 Unix 下的 compress(有专利纠纷)。通常 gzip 会与归档工具 tar 结合使用来生成压缩的归档格式,文件扩展名为 .tar.gz。 1995年,Info-ZIP 小组成员Jean-loup Gailly 和 Mark Adler 基于 gzip 源码中的 deflate 算法实现,推出了压缩库:zlib 。通过库函数调用的方式,为其他场景(如PNG压缩)提供通用的压缩/解压缩能力。同年,在 RFC 中发布了 DEFLATE、ZLIB、GZIP 三种数据压缩格式。其中 DEFLATE 是原始压缩数据流格式,ZLIB、GZIP 则是在前者的基础上包装数据头及校验逻辑等。此后随着 zip、gzip 工具及 zlib 库的广泛应用,deflate 成为互联网时代数据压缩格式的事实标准。 2010年后,各大型互联网公司陆续开源了新的压缩算法及实现,如:LZFSE(Apple)、(Google)、(Facebook)等,在压缩速度和压缩比方面均有不同程度的提升。常见的压缩库如下(需要注意的是:由于压缩算法协议的差异,这些函数库不能交叉使用,数据压缩/解压缩必须使用同一种算法操作):
3 压缩技术在 Java 中的应用及优化思路
| 3.1 Java 语言中压缩/解压缩 API 实现原理
public class ZipUtil {
//压缩
public void compress(File file, File zipFile) {
byte[] buffer = new byte[1024];
try {
InputStream input = new FileInputStream(file);
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
zipOut.putNextEntry(new ZipEntry(file.getName()));
int length = 0;
while ((length = input.read(buffer)) != -1) {
zipOut.write(buffer, 0, length);
}
input.close();
zipOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//解压缩
public void uncompress(File file, File outFile) {
byte[] buffer = new byte[1024];
try {
ZipInputStream input = new ZipInputStream(new FileInputStream(file));
OutputStream output = new FileOutputStream(outFile);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdir();
}
if (!outFile.exists()) {
outFile.createNewFile();
}
int length = 0;
while ((length = input.read(buffer)) != -1) {
output.write(buffer, 0, length);
}
input.close();
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class GZipUtil {
public void compress(File file, File outFile) {
byte[] buffer = new byte[1024];
try {
InputStream input = new FileInputStream(file);
GZIPOutputStream gzip = new GZIPOutputStream(new FileOutputStream(outFile));
int length = 0;
while ((length = input.read(buffer)) != -1) {
gzip.write(buffer, 0, length);
}
input.close();
gzip.finish();
gzip.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void uncompress(File file, File outFile) {
try {
FileOutputStream out = new FileOutputStream(outFile);
GZIPInputStream ungzip = new GZIPInputStream(new FileInputStream(file));
byte[] buffer = new byte[1024];
int n;
while ((n = ungzip.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
ungzip.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.8.4</version>
</dependency>
public class SnappyDemo {
public static void main(String[] args) {
String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper of "
+ "Snappy, a fast compresser/decompresser.";
byte[] compressed = new byte[0];
try {
compressed = Snappy.compress(input.getBytes("UTF-8"));
byte[] uncompressed = Snappy.uncompress(compressed);
String result = new String(uncompressed, "UTF-8");
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
}
| 3.2 MJDK 优化方案
3.2.1 优化思路
1. zlib 改造流程(重点在 API 的兼容性改造)
优化后的 mzlib 库在线上稳定运行 3 年以上,压缩速率提升在 5 倍以上,有效解决了上文提到基础研发平台曾在镜像构建、图片处理等场景面临过压缩/解压缩耗时较高的问题。
3.2.2 优化效果
测试集: 测试内容:GZip 压缩/解压缩文件、Zip 压缩/解压缩文件
兼容性测试(通过):改造后的 Java 类库的 Zip、Gzip 压缩/解压缩接口可正常使用,与原生 JDK 中的接口交叉进行压缩/解压缩操作验证通过。 性能测试(通过):在同一基准 update 版本下,MJDK8_mzlib 数据压缩耗时比 OpenJDK8 降低 5-10 倍,压缩比无较大波动(增加 3% 左右)。
4 本文作者
5 参考文献
[1] [2]
:使用 zlib 以实作网路协定的压缩、的压缩以及开机时解压缩自身的核心。 Libpng:用于 图形格式的一个实现,对 数据规定了 DEFLATE 作为流压缩方法。 HTTP协议:使用 zlib 对 HTTP 响应头数据进行压缩/解压缩。 、:以 zlib 达到最佳化加密网路传输。 、 和 等,使用 zlib 来压缩和远端仓库的通讯流量。 和 等包管理软件:以 zlib 解压缩 RPM 或者其他封包。
---------- END ----------
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...