package com.imyeyu.compress; import com.imyeyu.io.IO; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; /** * Zip 解压器 * * @author 夜雨 * @version 2024-06-30 19:47 */ public class ZipDecompressor extends Decompressor { @Override public void run(File fromFile, String toPath) throws Exception { initByteProgress(readTotalSize(fromFile)); try { super.run(fromFile, toPath); } finally { resetProgress(); } } @Override public void run(InputStream fromStream, String toPath) throws Exception { try (ZipInputStream zipInputStream = new ZipInputStream(nonClosing(fromStream))) { ZipEntry entry; boolean processed = false; while ((entry = zipInputStream.getNextEntry()) != null) { String path = IO.fitPath(toPath) + entry.getName(); if (entry.isDirectory()) { IO.dir(path); } else { File toFile = IO.file(path); try (OutputStream outputStream = IO.getOutputStream(toFile)) { transfer(zipInputStream, outputStream); outputStream.flush(); } handleFile(toFile); processed = true; } zipInputStream.closeEntry(); } if (processed) { finishProgress(); } } } /** * 读取压缩包解压总字节数 * * @param fromFile 压缩文件 * @return 总字节数,未知时返回 -1 * @throws Exception 读取失败 */ private long readTotalSize(File fromFile) throws Exception { long totalSize = 0L; try (ZipFile zipFile = new ZipFile(fromFile)) { Enumeration entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) { continue; } long size = entry.getSize(); if (size < 0L) { return -1L; } totalSize += size; } } return totalSize; } }