diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java index 315d2f826..1c797a6db 100755 --- a/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ZipUtil.java @@ -30,6 +30,7 @@ import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.function.Consumer; import java.util.zip.ZipEntry; @@ -558,6 +559,37 @@ public class ZipUtil { return outFile; } + /** + * 限制解压后文件大小 + * + * @param zipFile zip文件,附带编码信息,使用完毕自动关闭 + * @param outFile 解压到的目录 + * @param size 警戒线大小(B) + * @return 解压的目录 + * @throws IORuntimeException IO异常 + * @since 5.8.5 + */ + public static File unzip(ZipFile zipFile, File outFile, long size) throws IORuntimeException { + if (outFile.exists() && outFile.isFile()) { + throw new IllegalArgumentException( + StrUtil.format("Target path [{}] exist!", outFile.getAbsolutePath())); + } + Enumeration zipEntries = zipFile.entries(); + long zipFileSize = 0L; + while(zipEntries.hasMoreElements()) { + ZipEntry zipEntry = zipEntries.nextElement(); + zipFileSize += zipEntry.getSize(); + if (zipFileSize > size) { + throw new IllegalArgumentException("The file size exceeds the limit"); + } + } + + try (final ZipReader reader = new ZipReader(zipFile)) { + reader.readTo(outFile); + } + return outFile; + } + /** * 获取压缩包中的指定文件流 * diff --git a/hutool-core/src/test/java/cn/hutool/core/util/ZipUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/ZipUtilTest.java index 5b9462a55..d01f51ef8 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/ZipUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/ZipUtilTest.java @@ -16,6 +16,9 @@ import java.io.OutputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import java.util.zip.ZipFile; + +import static cn.hutool.core.util.ZipUtil.unzip; /** * {@link ZipUtil}单元测试 @@ -195,4 +198,18 @@ public class ZipUtilTest { ZipUtil.zip(FileUtil.file("d:\\test\\qr.zip"),false,dd); } + + @Test + public void SizeUnzip() throws IOException { + String zipPath = "F:\\BaiduNetdiskDownload\\demo.zip"; + String outPath = "F:\\BaiduNetdiskDownload\\test"; + ZipFile zipFile = new ZipFile(zipPath, Charset.forName("GBK")); + File file = new File(outPath); + // 限制解压文件大小为637KB + long size = 637*1024L; + + // 限制解压文件大小为636KB + // long size = 636*1024L; + unzip(zipFile, file, size); + } }