1:加载依赖
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
2:实现代码
import net.sf.sevenzipjbinding.*;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* 文件解压缩工具类
*/
public class FileUtil {
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
/**
* rar解压缩
* @param rarFile rar文件的全路径
* @param outPath 解压路径
* @return 压缩包中所有的文件
*/
public static void unRarZip7Z(String rarFile, String outPath, String pwd) throws Exception {
if (rarFile.toLowerCase().endsWith(".zip")) {
if(StringUtils.isEmpty(pwd)){
unZip(rarFile, outPath, false);
}else{
ZipCompressUtil.unZip(rarFile,outPath,pwd);
}
} else if (rarFile.toLowerCase().endsWith(".rar")) {
unRar(rarFile, outPath, pwd);
} else if (rarFile.toLowerCase().endsWith(".7z")) {
un7z(rarFile, outPath);
}
}
/**
* rar解压缩
* @param rarFile rar文件的全路径
* @param outPath 解压路径
* @return 压缩包中所有的文件
*/
private static String unRar(String rarFile, String outPath, String passWord) {
RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
try {
// 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
randomAccessFile = new RandomAccessFile(rarFile, "r");
if (StringUtils.isNotBlank(passWord)) {
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile), passWord);
} else {
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
}
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
final int[] hash = new int[]{0};
if (!item.isFolder()) {
ExtractOperationResult result;
final long[] sizeArray = new long[1];
File outFile = new File(outPath + File.separator+ item.getPath());
File parent = outFile.getParentFile();
if ((!parent.exists()) && (!parent.mkdirs())) {
continue;
}
if (StringUtils.isNotBlank(passWord)) {
result = item.extractSlow(data -> {
try {
IOUtils.write(data, new FileOutputStream(outFile, true));
} catch (Exception e) {
e.printStackTrace();
}
hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed
}, passWord);
} else {
result = item.extractSlow(data -> {
try {
IOUtils.write(data, new FileOutputStream(outFile, true));
} catch (Exception e) {
e.printStackTrace();
}
hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed
});
}
if (result == ExtractOperationResult.OK) {
log.error("解压rar成功...." + String.format("%9X | %10s | %s", hash[0], sizeArray[0], item.getPath()));
} else if (StringUtils.isNotBlank(passWord)) {
log.error("解压rar成功:密码错误或者其他错误...." + result);
return "password";
} else {
return "rar error";
}
}
}
} catch (Exception e) {
log.error("unRar error", e);
return e.getMessage();
} finally {
try {
inArchive.close();
randomAccessFile.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return "";
}
/**
* 获取压缩包中的全部文件
* @param path 文件夹路径
* @childName 每一个文件的每一层的路径==D==区分层数
* @return 压缩包中所有的文件
*/
private static Map<String, String> getFileNameList(String path, String childName) {
System.out.println("path:" + path + "---childName:"+childName);
Map<String, String> files = new HashMap<>();
File file = new File(path); // 需要获取的文件的路径
String[] fileNameLists = file.list(); // 存储文件名的String数组
File[] filePathLists = file.listFiles(); // 存储文件路径的String数组
for (int i = 0; i < filePathLists.length; i++) {
if (filePathLists[i].isFile()) {
files.put(fileNameLists[i] + "==D==" + childName, path + File.separator + filePathLists[i].getName());
} else {
files.putAll(getFileNameList(path + File.separator + filePathLists[i].getName(), childName + "&" + filePathLists[i].getName()));
}
}
return files;
}
/**
* zip解压缩
* @param zipFilePath zip文件的全路径
* @param unzipFilePath 解压后文件保存路径
* @param includeZipFileName 解压后文件是否包含压缩包文件名,true包含,false不包含
* @return 压缩包中所有的文件
*/
public static Map<String, String> unZip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception{
File zipFile = new File(zipFilePath);
//如果包含压缩包文件名,则处理保存路径
if(includeZipFileName){
String fileName = zipFile.getName();
if(StringUtils.isNotEmpty(fileName)){
fileName = fileName.substring(0,fileName.lastIndexOf("."));
}
unzipFilePath = unzipFilePath + File.separator + fileName;
}
//判断保存路径是否存在,不存在则创建
File unzipFileDir = new File(unzipFilePath);
if(!unzipFileDir.exists() || !unzipFileDir.isDirectory()){
unzipFileDir.mkdirs();
}
//开始解压
ZipEntry entry = null;
String entryFilePath = null, entryDirPath = "";
File entryFile = null, entryDir = null;
int index = 0, count = 0, bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
Charset gbk = Charset.forName("GBK");
ZipFile zip = new ZipFile(zipFile, gbk);
try {
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
while (entries.hasMoreElements()) {
entry = entries.nextElement();
entryFilePath = unzipFilePath + File.separator + entry.getName();
entryFilePath = entryFilePath.replace("/", File.separator);
index = entryFilePath.lastIndexOf(File.separator);
if (index != -1) {
entryDirPath = entryFilePath.substring(0, index);
}
entryDir = new File(entryDirPath);
if (!entryDir.exists() || !entryDir.isDirectory()) {
entryDir.mkdirs();
}
entryFile = new File(entryFilePath);
//判断当前文件父类路径是否存在,不存在则创建
if(!entryFile.getParentFile().exists() || !entryFile.getParentFile().isDirectory()){
entryFile.getParentFile().mkdirs();
}
//不是文件说明是文件夹创建即可,无需写入
if(entryFile.isDirectory()){
continue;
}
bos = new BufferedOutputStream(new FileOutputStream(entryFile));
bis = new BufferedInputStream(zip.getInputStream(entry));
while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
bos.write(buffer, 0, count);
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
bos.flush();
bos.close();
bis.close();
zip.close();
}
Map<String, String> resultMap = getFileNameList(unzipFilePath, "");
return resultMap;
}
/**
* zip解压缩
* @param zipFilePath zip文件的全路径
* @param includeZipFileName 解压后文件是否包含压缩包文件名,true包含,false不包含
* @return 压缩包中所有的文件
*/
public static Map<String, String> unZip(String zipFilePath, boolean includeZipFileName) throws Exception{
File zipFile = new File(zipFilePath);
String unzipFilePath = zipFilePath.substring(0, zipFilePath.lastIndexOf(File.separator));
//如果包含压缩包文件名,则处理保存路径
if(includeZipFileName){
String fileName = zipFile.getName();
if(StringUtils.isNotEmpty(fileName)){
fileName = fileName.substring(0,fileName.lastIndexOf("."));
}
unzipFilePath = unzipFilePath + File.separator + fileName;
}
//判断保存路径是否存在,不存在则创建
File unzipFileDir = new File(unzipFilePath);
if(!unzipFileDir.exists() || !unzipFileDir.isDirectory()){
unzipFileDir.mkdirs();
}
//开始解压
ZipEntry entry = null;
String entryFilePath = null, entryDirPath = "";
File entryFile = null, entryDir = null;
int index = 0, count = 0, bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
Charset gbk = Charset.forName("GBK");
ZipFile zip = new ZipFile(zipFile, gbk);
try {
Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
while (entries.hasMoreElements()) {
entry = entries.nextElement();
entryFilePath = unzipFilePath + File.separator + entry.getName();
entryFilePath = entryFilePath.replace("/", File.separator);
index = entryFilePath.lastIndexOf(File.separator);
if (index != -1) {
entryDirPath = entryFilePath.substring(0, index);
}
entryDir = new File(entryDirPath);
if (!entryDir.exists() || !entryDir.isDirectory()) {
entryDir.mkdirs();
}
entryFile = new File(entryFilePath);
//判断当前文件父类路径是否存在,不存在则创建
if(!entryFile.getParentFile().exists() || !entryFile.getParentFile().isDirectory()){
entryFile.getParentFile().mkdirs();
}
//不是文件说明是文件夹创建即可,无需写入
if(entryFile.isDirectory()){
continue;
}
bos = new BufferedOutputStream(new FileOutputStream(entryFile));
bis = new BufferedInputStream(zip.getInputStream(entry));
while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
bos.write(buffer, 0, count);
}
bos.flush();
bos.close();
bis.close();
}
}catch (Exception e){
e.printStackTrace();
}finally {
zip.close();
}
Map<String, String> resultMap = getFileNameList(unzipFilePath, "");
return resultMap;
}
/**
* 7z解压缩
* @param z7zFilePath 7z文件的全路径
* @param outPath 解压路径
* @return 压缩包中所有的文件
*/
public static Map<String, String> un7z(String z7zFilePath, String outPath){
SevenZFile zIn = null;
try {
File file = new File(z7zFilePath);
zIn = new SevenZFile(file);
SevenZArchiveEntry entry = null;
File newFile = null;
while ((entry = zIn.getNextEntry()) != null){
//不是文件夹就进行解压
if(!entry.isDirectory()){
newFile = new File(outPath, entry.getName());
if(!newFile.exists()){
new File(newFile.getParent()).mkdirs(); //创建此文件的上层目录
}
OutputStream out = new FileOutputStream(newFile);
BufferedOutputStream bos = new BufferedOutputStream(out);
int len = -1;
byte[] buf = new byte[(int)entry.getSize()];
while ((len = zIn.read(buf)) != -1){
bos.write(buf, 0, len);
}
bos.flush();
bos.close();
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (zIn != null) {
zIn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Map<String, String> resultMap = getFileNameList(outPath, "");
return resultMap;
}
}
public class ZipCompressUtil {
private static final Logger LOG = LoggerFactory.getLogger(ZipCompressUtil.class);
/**
* GZip 解压缩
*
* @param byteArray GZip格式的压缩字节数组
* @return 解压缩后的字符串结果
*/
public static String unCompress(byte[] byteArray) {
if (byteArray == null || byteArray.length == 0) {
return null;
}
String unCompressString = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(byteArray);
try {
GZIPInputStream gzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = gzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
unCompressString = out.toString();
gzip.close();
} catch (IOException e) {
LOG.error(e.getMessage(), e);
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
LOG.error(e.getMessage(), e);
}
}
return unCompressString;
}
/**
* 使用给定密码压缩指定文件或文件夹到指定位置.
* <p>
* dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者""
* 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀;
* 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名.
*
* @param src 要压缩的文件或文件夹路径
* @param dest 压缩文件存放路径
* @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效.
* 如果为false,将直接压缩目录下文件到压缩文件.
* @param passwd 压缩使用的密码
* @return 最终的压缩文件存放的绝对路径, 如果为null则说明压缩失败.
*/
public static String zip(String src, String dest, boolean isCreateDir, String passwd) {
File srcFile = new File(src);
dest = buildDestinationZipFilePath(srcFile, dest);
ZipParameters parameters = new ZipParameters();
// 压缩方式
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// 压缩级别
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if (!StringUtils.isEmpty(passwd)) {
parameters.setEncryptFiles(true);
// 加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword(passwd.toCharArray());
}
try {
ZipFile zipFile = new ZipFile(dest);
if (srcFile.isDirectory()) {
// 如果不创建目录的话,将直接把给定目录下的文件压缩到压缩文件,即没有目录结构
if (!isCreateDir) {
File[] subFiles = srcFile.listFiles();
ArrayList<File> temp = new ArrayList<File>();
Collections.addAll(temp, subFiles);
zipFile.addFiles(temp, parameters);
return dest;
}
zipFile.addFolder(srcFile, parameters);
} else {
zipFile.addFile(srcFile, parameters);
}
return dest;
} catch (ZipException e) {
e.printStackTrace();
}
return null;
}
/**
* @param source
* 原始文件路径
* @param dest
* 解压路径
* @param password
* 解压文件密码(可以为空)
*/
public static void unZip(String source, String dest, String password) {
try {
File zipFile = new File(source);
// 首先创建ZipFile指向磁盘上的.zip文件
ZipFile zFile = new ZipFile(zipFile);
zFile.setFileNameCharset("GBK");
File destDir = new File(dest);
if (!destDir.exists()) {
destDir.mkdirs();
}
if (zFile.isEncrypted()) {
// 设置密码
zFile.setPassword(password.toCharArray());
}
// 将文件抽出到解压目录(解压)
zFile.extractAll(dest);
List<FileHeader> headerList = zFile.getFileHeaders();
List<File> extractedFileList = new ArrayList<File>();
for (FileHeader fileHeader : headerList) {
if (!fileHeader.isDirectory()) {
extractedFileList.add(new File(destDir, fileHeader.getFileName()));
}
}
File[] extractedFiles = new File[extractedFileList.size()];
extractedFileList.toArray(extractedFiles);
for (File f : extractedFileList) {
System.out.println(f.getAbsolutePath() + "文件解压成功!");
}
} catch (ZipException e) {
e.printStackTrace();
}
}
/**
* 构建压缩文件存放路径,如果不存在将会创建
* 传入的可能是文件名或者目录,也可能不传,此方法用以转换最终压缩文件的存放路径
*
* @param srcFile 源文件
* @param destParam 压缩目标路径
* @return 正确的压缩文件存放路径
*/
private static String buildDestinationZipFilePath(File srcFile, String destParam) {
if (StringUtils.isEmpty(destParam)) {
if (srcFile.isDirectory()) {
destParam = srcFile.getParent() + File.separator + srcFile.getName() + ".zip";
} else {
String fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));
destParam = srcFile.getParent() + File.separator + fileName + ".zip";
}
} else {
// 在指定路径不存在的情况下将其创建出来
createDestDirectoryIfNecessary(destParam);
if (destParam.endsWith(File.separator)) {
String fileName = "";
if (srcFile.isDirectory()) {
fileName = srcFile.getName();
} else {
fileName = srcFile.getName().substring(0, srcFile.getName().lastIndexOf("."));
}
destParam += fileName + ".zip";
}
}
return destParam;
}
/**
* 在必要的情况下创建压缩文件存放目录,比如指定的存放路径并没有被创建
*
* @param destParam 指定的存放路径,有可能该路径并没有被创建
*/
private static void createDestDirectoryIfNecessary(String destParam) {
File destDir = null;
if (destParam.endsWith(File.separator)) {
destDir = new File(destParam);
} else {
destDir = new File(destParam.substring(0, destParam.lastIndexOf(File.separator)));
}
if (!destDir.exists()) {
destDir.mkdirs();
}
}
}