不要脑子,拿走就用(但目录结构)
package org.cn.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** * @Description ZIP压缩、解压缩工具类 * @Date 2023/6/28 15:14 * @Author xingjp * @Version 1.0 **/ public class ZipUtil { private static final Logger LOG = LoggerFactory.getLogger(ZipUtil.class); /** * 文件后缀 */ private static final String ZIP = ".zip"; /** * 缓冲流大小 */ private static final int BUFFER = 1024; /** * 测试 */ public static void main(String[] args) throws IOException { //压缩文件测试 String srcPath = "D:\\java\\"; String zipFilePath = "D:\\java\\test.zip"; zipFile(srcPath, zipFilePath); //解压文件测试 String zipFilePath = "D:\\java\\test.zip"; String targetPath = "D:\\java\\"; unzipFile(zipFilePath, targetPath); } /** * 压缩文件 * @param srcPath 需要压缩的文件路径 * @param zipFilePath 压缩后路径(全路径,包含文件名) */ private static void zipFile(String srcPath, String zipFilePath) throws IOException { LOG.info("【文件压缩】---文件路径:{},压缩后路径:{},开始压缩...", srcPath, zipFilePath); File srcFile = new File(srcPath); // 校验文件是否存在 if (!srcFile.exists()) { throw new FileNotFoundException("文件不存在"); } // 校验压缩路径是否符合格式 if (!zipFilePath.endsWith(ZIP)) { throw new InvalidParameterException("压缩路径不正确"); } // 如果压缩文件已存在,先删除 File zipFile = new File(zipFilePath); if (zipFile.exists()) { Files.delete(zipFile.toPath()); } // 获取文件中的所有文件 List<File> files = getFiles(srcFile); // 缓冲流 byte[] buffer = new byte[BUFFER]; // 读出长度 int length; // 输出流过滤器。用于以ZIP文件格式写入文件 try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath))) { for (File file : files) { // 获取源文件的父目录 String srcFileParent = srcFile.getParent(); String parent = srcFileParent.endsWith(File.separator) ? srcFileParent.replace(String.valueOf(File.separatorChar), "") : srcFileParent; // 压缩目录的根目录与当前文件夹保持一致 String name = file.getPath().replace(parent + File.separator, ""); // ZIP文件项 ZipEntry zipEntry = new ZipEntry(file.isFile() ? name : name + File.separator); // 未压缩的字节大小 zipEntry.setSize(file.length()); // 最后修改时间 zipEntry.setTime(file.lastModified()); // 压缩方法 默认 ZipEntry.DEFLATED -1 zipEntry.setMethod(ZipEntry.DEFLATED); // 写入ZIP条目 zipOutputStream.putNextEntry(zipEntry); if (file.isFile()) { InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); while ((length = inputStream.read(buffer, 0, BUFFER)) != -1) { zipOutputStream.write(buffer, 0, length); } inputStream.close(); } } LOG.info("【文件压缩】---文件路径:{},压缩后路径:{},压缩成功!!!", srcPath, zipFilePath); } catch (IOException e) { LOG.error("【文件压缩】---压缩文件:{},异常:", srcPath, e); throw new IOException("压缩失败,原因:" + e.getMessage()); } } /** * 获取文件中的所有文件 */ private static List<File> getFiles(File srcFile) { List<File> list = new ArrayList<>(8); // 判断文件是否是普通文件, 如果是普通文件则直接放入集合 if (srcFile.isFile()) { list.add(srcFile); return list; } // 判断文件是否是文件夹 if (srcFile.isDirectory()) { File[] files = srcFile.listFiles(); // 如果是空文件夹,则直接放入集合 if (null == files || files.length == 0) { list.add(srcFile); return list; } // 递归获取所有文件 for (File file : files) { list.addAll(getFiles(file)); } } return list; } /** * 解压文件到指定目录 * @param zipFilePath 压缩文件路径(全路径,包含文件名) * @param targetPath 解压后路径 */ private static void unzipFile(String zipFilePath, String targetPath) throws IOException { LOG.info("【文件解压】---压缩文件路径:{},解压后路径:{},开始解压...", zipFilePath, targetPath); // 校验文件是否存在 File zipFile = new File(zipFilePath); if (!zipFile.exists()) { throw new FileNotFoundException("压缩文件不存在"); } // 校验压缩路径是否符合格式 if (!zipFilePath.endsWith(ZIP)) { throw new InvalidParameterException("压缩路径不正确"); } // 输入流过滤器.用于读取ZIP文件格式的文件 try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) { // ZIP文件项 ZipEntry zipEntry; byte[] buffer = new byte[BUFFER]; int length; while ((zipEntry = zipInputStream.getNextEntry()) != null) { // 如果文件不存在,则需创建文件 File file = new File(targetPath + File.separator + zipEntry.getName()); if (zipEntry.getName().endsWith(File.separator) && !file.exists()) { file.mkdirs(); continue; } // 如果父包不存在则创建 final File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } // 如果不是文件夹则写入,如果文件存在则删除覆盖 if (!file.isDirectory()) { OutputStream outputStream = new FileOutputStream(file); while ((length = zipInputStream.read(buffer, 0, BUFFER)) != -1) { outputStream.write(buffer, 0, length); } outputStream.close(); } } LOG.info("【文件解压】---压缩文件路径:{},解压后路径:{},解压成功!!!", zipFilePath, targetPath); } catch (IOException e) { LOG.error("【文件解压】---压缩文件:{},异常:", zipFilePath, e); throw new IOException("解压失败,原因:" + e.getMessage()); } } }
2.支持多成结构文件的解压
/**
* 解压测试方法
* @param args
*/
public static void main(String[] args) {
File sourefile = new File("D:\\java/test.zip");
String dest = "D:\\java/test";
unZip(sourefile,dest);
System.out.println("解压成功!");
}
/* 文件解压
*
* @param File 要解压的文件路径 srcFile
* @param String 要解压到那个路径 destDirPath
*/
public static void unZip(File srcFile,String destDirPath){
long start = System.currentTimeMillis();
// 判断源文件是否存在
if (!srcFile.exists()) {
throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
}
// 开始解压
ZipFile zipFile = null;
try {
zipFile = new ZipFile(srcFile);
Enumeration<?> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
System.out.println("解压" + entry.getName());
// 如果是文件夹,就创建个文件夹
if (entry.isDirectory()) {
String dirPath = destDirPath + "/" + entry.getName();
File dir = new File(dirPath);
dir.mkdirs();
} else {
// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
File targetFile = new File(destDirPath + "/" + entry.getName());
// 保证这个文件的父文件夹必须要存在
if(!targetFile.getParentFile().exists()){
targetFile.getParentFile().mkdirs();
}
targetFile.createNewFile();
// 将压缩文件内容写入到这个文件中
InputStream is = zipFile.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(targetFile);
int len;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
// 关流顺序,先打开的后关闭
fos.close();
is.close();
}
}
long end = System.currentTimeMillis();
System.out.println("解压完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("unzip error from ZipUtils", e);
} finally {
if(zipFile != null){
try {
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}