7z是一种主流高效的压缩格式,拥有极高的压缩比。7z是一种可以使用多种压缩算法进行数据压缩的档案格式。通常使用7z格式能比zip格式的压缩文件小20%-70%,但是在时间和空间上需要更大的消耗。
7z已公开了结构编辑功能,所以它可以支持任何一种新的压缩算法。到目前为止,下列压缩算法已被整合到了 7z中:
压缩算法 | 备注 |
---|---|
LZMA | 改良与优化后的LZ77算法 |
LZMA2 | 改良的LZMA算法 |
PPMD | 基于Dmitry ShkarinDE PPMdH算法 |
BCJ | 32位x86可执行文件转换程序 |
BCJ2 | 32位x86可执行文件转换程序 |
BZip2 | 标准BWT算法 |
Deflate | 标准LZ77-based算法 |
关于7z的算法介绍及特征等描述信息,可以自行百度查看。
本文针对磁盘上进行压缩和解压演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。
· Maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.8</version>
</dependency>
· 磁盘压缩和解压
无特殊情况下,操作都是在磁盘上进行,将所有文件存放在某一目录中,然后对目录进行压缩,工具类代码如下:
package com.arhorchin.securitit.compress.sevenz;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
public class SevenZDiskUtil {
/**
* 7z 压缩.
* @param srcDirPath 待压缩目录.
* @param tarFilePath 压缩文件路径.
* @throws Exception .
*/
public static void sevenZCompress(String srcDirPath, String tarFilePath) throws Exception {
SevenZArchiveEntry archiveEntry = null;
File sevenZFile = null;
File seveZTarFile = null;
SevenZOutputFile sevenZOutputFile = null;
File[] sevenZFileList = null;
FileInputStream sevenZFis = null;
BufferedInputStream sevenBis = null;
try {
sevenZFile = new File(srcDirPath);
seveZTarFile = new File(tarFilePath);
sevenZOutputFile = new SevenZOutputFile(seveZTarFile);
sevenZFileList = sevenZFile.listFiles();
if (null == sevenZFileList || sevenZFileList.length <= 0) {
return;
}
for (File file : sevenZFileList) {
sevenZFis = new FileInputStream(file);
sevenBis = new BufferedInputStream(sevenZFis);
archiveEntry = sevenZOutputFile.createArchiveEntry(file, file.getName());
sevenZOutputFile.putArchiveEntry(archiveEntry);
int len = -1;
// 将源文件写入到7z文件中.
byte[] buf = new byte[1024];
while ((len = sevenBis.read(buf)) != -1) {
sevenZOutputFile.write(buf, 0, len);
}
}
sevenBis.close();
sevenZFis.close();
sevenZOutputFile.closeArchiveEntry();
} finally {
if (null != sevenBis) {
sevenBis.close();
}
if (null != sevenZFis) {
sevenZFis.close();
}
if (null != sevenZOutputFile) {
sevenZOutputFile.close();
}
}
}
/**
* 7z 解压.
* @param srcFilePath 待解压文件路径.
* @param tarDirPath 解压后文件目录.
* @throws Exception .
*/
public static void sevenZDecompress(String srcFilePath, String tarDirPath) throws Exception {
SevenZArchiveEntry archiveEntry = null;
File sevenZSrcFile = null;
SevenZFile sevenZFile = null;
OutputStream sevenZOs = null;
OutputStream sevenZBos = null;
try {
sevenZSrcFile = new File(srcFilePath);
// 针对压缩文件开始解压.
sevenZFile = new SevenZFile(sevenZSrcFile);
File file = null;
while ((archiveEntry = sevenZFile.getNextEntry()) != null) {
if (!archiveEntry.isDirectory()) {
file = new File(tarDirPath, archiveEntry.getName());
// 创建此文件的上级目录.
if (!file.exists()) {
new File(file.getParent()).mkdirs();
}
sevenZOs = new FileOutputStream(file);
sevenZBos = new BufferedOutputStream(sevenZOs);
int len = -1;
byte[] buf = new byte[1024];
while ((len = sevenZFile.read(buf)) != -1) {
sevenZOs.write(buf, 0, len);
}
}
}
} finally {
if (null != sevenZOs) {
sevenZOs.close();
}
if (null != sevenZBos) {
sevenZBos.close();
}
if (null != sevenZFile) {
sevenZFile.close();
}
}
}
}
测试代码如下:
package com.arhorchin.securitit.com.compress;
import com.arhorchin.securitit.compress.sevenz.SevenZDiskUtil;
public class SevenZDiskUtilTester {
public static void main(String[] args) throws Exception {
String srcDirPath = "C:/Users/Administrator/Downloads/个人文件/7z-test";
String tarFilePath = "C:/Users/Administrator/Downloads/个人文件/7z-test.7z";
SevenZDiskUtil.sevenZCompress(srcDirPath, tarFilePath);
String srcFilePath = "C:/Users/Administrator/Downloads/个人文件/7z-test.7z";
String tarSrcPath = "C:/Users/Administrator/Downloads/个人文件/7z-test-de";
SevenZDiskUtil.sevenZDecompress(srcFilePath, tarSrcPath);
}
}
· 总结
使用7z压缩格式可以取得更高的压缩比,当然,任何事情发生都是有前提的,在对不同类型或不同内容文件进行压缩时,压缩比会存在变动,并不会一直稳定在某个水准。总的来说,抛开条件谈性能、谈效率,都是耍流氓。在传输或存储时,对文件大小有要求的场景下,可以使用此种压缩格式。但同时也要注意7z高压缩比所带来的负面影响,以便在系统或功能设计时,可以提前预知风险且提早进行风险防控。