Java压缩和解压缩(四)7-Zip-Jbinding实践
Java压缩和解压缩admin 发布于:2023-03-05 00:31:02
阅读:loading
7-Zip-jbinding是一个免费的跨平台java绑定7-Zip免费压缩/解压缩库,7z archiver引擎的Java包装器,内置了多个动态链接库文件来适配不同的操作系统,支持Linux、Windows、Mac,以及32/64位系统的支持,可实现应用的跨平台,支持多种压缩格式的文件,如:7zip、zip、gzip、rar(rar4和rar5)、tar、iso 等多种常见格式;支持压缩包文件的提取、分割卷的提、支持密码的压缩和解压缩、多线程等,对于程序的自动适配和兼容支持的比较友好。
7-Zip-JBinding 是一个c++版7-Zip的封装,由两部分组成:java部分和本机部分。java部分介绍了7-Zip库的跨平台java接口,7-Zip-jbinding的本机部分通过java jni接口与java部分通信,并使用相应的本机7-Zip接口进行操作,所以它的性能要比java.util.zip提供的API要高,官网也对应提供了一系列示例,可自行掌握了解,参考它的应用结构图为:
package cn.chendd.compress;
import cn.chendd.compress.sevenz.CompressOutItemStructure;
import cn.chendd.compress.sevenz.Item;
import cn.chendd.compress.sevenz.SevenZCompressCallBack;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.IOutCreateArchive7z;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
/**
* @author chendd
* @date 2023/3/5 19:20
*/
public class CompressRar {
/**
* 压缩文件(夹)
* @param compressFile 压缩文件
* @param sevenZipFile 压缩后的文件
* @return 压缩的文件列表
*/
public static List<File> sevenZ(File compressFile, File sevenZipFile) {
return sevenZ(compressFile , sevenZipFile , null);
}
/**
* 带密码的文件(夹)压缩
* @param compressFile 压缩文件
* @param sevenZipFile 压缩后的文件
* @param password 密码
* @return 压缩的文件列表
*/
public static List<File> sevenZ(File compressFile, File sevenZipFile, String password) {
//构建输出压缩对象
IOutCreateArchive7z outArchive = null;
RandomAccessFileOutStream outStream = null;
List<File> resultList = Lists.newArrayList();
try {
outArchive = SevenZip.openOutArchive7z();
if (! sevenZipFile.getParentFile().exists()) {
sevenZipFile.getParentFile().mkdirs();
}
outStream = new RandomAccessFileOutStream(new RandomAccessFile(sevenZipFile, "rw"));
List<Item> items = CompressOutItemStructure.create(compressFile);
//压缩测试
outArchive.setLevel(5);
outArchive.setSolid(true);
//设置加密文件名
outArchive.setHeaderEncryption(true);
//创建压缩对象
outArchive.createArchive(outStream, items.size(), new SevenZCompressCallBack(compressFile, items , password));
items.forEach(item -> {
resultList.add(item.getFile());
});
return resultList;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (outStream != null) {
try {
outStream.close();
} catch (IOException ignore) {}
}
IOUtils.closeQuietly(outArchive);
}
}
/**
* 判断是否解压缩成功,判断标准:解压缩后的文件(夹)大于 解压前的文件
* @param srcFile 源压缩包文件
* @param destFile 解压缩后的文件
* @return true 解压缩后的文件 大于 解压缩前的文件大小
*/
public static boolean validatorUnSevenZ(File srcFile , File destFile) {
return FileUtils.sizeOf(destFile) > srcFile.length();
}
/**
* 解压缩
* @param zipFile 压缩包文件
* @param outFile 输出文件
* @return 文件夹列表
*/
public static List<File> unSevenZ(File zipFile , File outFile) {
return unSevenZ(zipFile , outFile , null);
}
/**
* 解压缩带密码文件
* @param zipFile 压缩包文件
* @param outFile 输出文件
* @param password 密码
* @return 文件列表
*/
public static List<File> unSevenZ(File zipFile , File outFile , String password) {
RandomAccessFileInStream inStream = null;
IInArchive inArchive = null;
boolean usePassword = StringUtils.isNotEmpty(password);
List<File> resultList = Lists.newArrayList();
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(zipFile, "r");
inStream = new RandomAccessFileInStream(randomAccessFile);
// 自动模式
if (usePassword) {
inArchive = SevenZip.openInArchive(null , inStream, password);
} else {
inArchive = SevenZip.openInArchive(null, inStream);
}
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
ISimpleInArchiveItem[] archiveItems = simpleInArchive.getArchiveItems();
for (ISimpleInArchiveItem item : archiveItems) {
RandomAccessFileOutStream rafo = null;
try {
File file;
if (item.isFolder()) {
new File(outFile , item.getPath()).mkdirs();
continue;
} else {
file = new File(outFile , item.getPath());
if (! file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
}
rafo = new RandomAccessFileOutStream(new RandomAccessFile(file , "rw"));
if (usePassword) {
item.extractSlow(rafo , password);
} else {
item.extractSlow(rafo);
}
resultList.add(file);
} finally {
if (rafo != null) {
rafo.close();
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(inStream);
IOUtils.closeQuietly(inArchive);
}
return resultList;
}
}
package cn.chendd.compress;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.MethodSorters;
import java.io.File;
/**
* 测试rar格式压缩包文件的操作
*
* @author chendd
* @date 2023/3/5 19:29
*/
@RunWith(JUnit4.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CompressRarTest {
/**
* 测试文件生成rar
*/
@Test
public void toRarFile() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/哈喽.txt");
File zipFile = new File(projectHome , "压缩文件夹/7zipjbinging_哈喽.rar");
CompressRar.sevenZ(file , zipFile);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试文件夹生成rar
*/
@Test
public void toRarFolder() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/复杂文件夹");
File zipFile = new File(projectHome , "压缩文件夹/7zipjbinging_复杂文件夹.rar");
CompressRar.sevenZ(file , zipFile);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 测试带密码的文件夹生成rar(加密文件名)
*/
@Test
public void toRarPasswordFolder() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File file = new File(projectHome , "源文件/简单文件夹");
File zipFile = new File(projectHome , "压缩文件夹/7zipjbinging_带密码_简单文件夹.rar");
CompressRar.sevenZ(file , zipFile , "https://www.chendd.cn");
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 解压缩 rar 文件
*/
@Test
public void unRarFile() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/7zipjbinging_复杂文件夹.rar");
File file = new File(projectHome , "解压缩文件夹/7zipjbinging_复杂文件夹");
CompressRar.unSevenZ(zipFile , file);
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("解压缩后文件:" + zipFile.getAbsolutePath());
}
/**
* 解压缩带密码的 rar 文件
*/
@Test
public void unRarPasswordFile() {
File projectHome = new File(System.getProperty("user.dir")).getParentFile();
File zipFile = new File(projectHome , "压缩文件夹/7zipjbinging_带密码_简单文件夹.rar");
File file = new File(projectHome , "解压缩文件夹/7zipjbinging_带密码_简单文件夹");
CompressRar.unSevenZ(zipFile , file , "https://www.chendd.cn");
System.out.println("压缩源文件:" + file.getAbsolutePath());
System.out.println("解压缩后文件:" + zipFile.getAbsolutePath());
}
}
(压缩文件示例)
(提取带密码的Rar文件预览)
(1)本文使用开源项目7-Zip-Jbinding 实现的“rar”格式文件(夹)的压缩和解压缩,仅以rar格式文件的操作进行示例实践;
(2)本文示例包含文件压缩、文件解压缩、文件夹压缩、文件夹解压缩、压缩包文件列表预览;
(4)本文示例支持压缩文件(夹)包含中文名称,支持带密码文件的压缩和解压缩;
(5)项目源码下载地:源码下载.txt;
点赞