记录一下递归解压压缩包的实现方法
这个方法可以直接使用
package com.shenyh.estimate.util;
import com.shenyh.exception.ServiceException;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;
import java.io.*;
import java.util.Enumeration;
import java.util.Objects;
public class FileRecursionUtil {
/**
* 递归解压zip文件
*
* @param zip zip文件路径
* @param targetPath 解压后存放的文件路径
* @return void
*/
public File unZipRecursion(File zip, String targetPath) {
unZip(zip, targetPath);
scanFilesWithRecursion(targetPath);
return new File(targetPath);
}
/**
* 解压zip文件
*
* @param srcFile zip文件路径
* @param destDirPath 解压后存放的文件路径
* @return boolean
*/
public boolean unZip(File srcFile, String destDirPath) {
//校验zip包格式
zipIsRight(srcFile);
// 开始解压
try (ZipFile zipFile = new ZipFile(srcFile)) {
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
// 如果是文件夹,就创建个文件夹
if (entry.isDirectory()) {
String dirPath = destDirPath + File.separator + entry.getName();
File dir = new File(dirPath);
dir.mkdirs();
} else {
// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
File targetFile = new File(destDirPath + File.separator + entry.getName());
// 保证这个文件的父文件夹必须要存在
if (!targetFile.getParentFile().exists()) {
targetFile.getParentFile().mkdirs();
}
boolean newFile = targetFile.createNewFile();
if (newFile) {
// 将压缩文件内容写入到这个文件中
try (InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile)) {
int len;
byte[] buf = new byte[2048];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 遍历文件夹,有压缩文件就进行解压
*
* @param folderPath 需要解压的文件夹路径
* @return void
*/
public void scanFilesWithRecursion(String folderPath) {
File directory = new File(folderPath);
// 遍历文件夹
if (directory.isDirectory()) {
File[] fileList = directory.listFiles();
for (int i = 0; i < Objects.requireNonNull(fileList).length; i++) {
String name = fileList[i].getAbsolutePath().substring(fileList[i].getAbsolutePath().lastIndexOf(".") + 1);
// 如果是zip文件,解密
if ("zip".equals(name)) {
boolean flag = unZip(new File(fileList[i].getAbsolutePath()), fileList[i].getParent());
if (flag) {
// 解压成功,删除压缩包
fileList[i].delete();
}
// 递归
scanFilesWithRecursion(fileList[i].getParent());
} else if (new File(fileList[i].getPath()).isDirectory()) {
// 递归
scanFilesWithRecursion(fileList[i].getPath());
}
}
}
}
/**
* 判断zip文件是否为正确的zip文件
*
* @param file
*/
public static void zipIsRight(File file) {
try (ZipFile zipFile = new ZipFile(file)) {
// 如果zip文件没有密码,那么可以正常打开,不会抛出异常
// 判断压缩包内容是否为空
if (zipIsNull(file)) {
throw new ServiceException("压缩包的内容为空!");
}
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
int method = entry.getMethod();
if (!isCommonCompressionMethod(method)) {
throw new ServiceException("请检查压缩包压缩方式是否为以下几种:标准压缩、BZIP2、LZMA、PPMD!");
}
}
} catch (IOException e) {
// 如果zip文件有密码,那么打开时会抛出IOException
throw new ServiceException("请不要上传带有密码的压缩包或者非法压缩包");
}
}
/**
* 判断zip内容是否为空
*/
public static boolean zipIsNull(File file) {
FileInputStream fis = null;
boolean flag = true;
try {
fis = new FileInputStream(file);
ZipArchiveInputStream zis = new ZipArchiveInputStream(fis);
ArchiveEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
flag = false;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(fis);
}
return flag;
}
/**
* 判断是否为常见的压缩方式
*/
private static boolean isCommonCompressionMethod(int method) {
return method == ZipArchiveEntry.STORED || // 0
method == ZipArchiveEntry.DEFLATED || // 8
method == 12 || // BZIP2
method == 14 || // LZMA
method == 98 || // PPMD
method == 9 //DEFLATED64
;
}
}
浙公网安备 33010602011771号