package com.imyeyu.compress; import com.imyeyu.io.IO; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; import java.io.File; import java.io.InputStream; import java.io.OutputStream; /** * Gzip 解压器 * 当前实现保持与原行为一致,实际按 tar.gz 解压 * * @author 夜雨 * @version 2024-06-30 19:47 */ public class GZipDecompressor 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 ( GzipCompressorInputStream gzipInputStream = new GzipCompressorInputStream(nonClosing(fromStream)); TarArchiveInputStream tarInputStream = new TarArchiveInputStream(gzipInputStream) ) { TarArchiveEntry entry; boolean processed = false; while ((entry = tarInputStream.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(tarInputStream, outputStream); outputStream.flush(); } handleFile(toFile); processed = true; } } if (processed) { finishProgress(); } } } /** * 读取压缩包解压总字节数 * * @param fromFile 压缩文件 * @return 总字节数 * @throws Exception 读取失败 */ private long readTotalSize(File fromFile) throws Exception { long totalSize = 0L; try ( InputStream inputStream = IO.getInputStream(fromFile); GzipCompressorInputStream gzipInputStream = new GzipCompressorInputStream(inputStream); TarArchiveInputStream tarInputStream = new TarArchiveInputStream(gzipInputStream) ) { TarArchiveEntry entry; while ((entry = tarInputStream.getNextEntry()) != null) { if (!entry.isDirectory()) { totalSize += entry.getSize(); } } } return totalSize; } }