├── src ├── main │ ├── resources │ │ └── application.properties │ └── java │ │ └── com │ │ └── h2t │ │ └── study │ │ ├── CompressUnpackApplication.java │ │ ├── enums │ │ └── FileTypeEnum.java │ │ ├── exception │ │ └── CustomException.java │ │ └── util │ │ ├── FileUtil.java │ │ ├── UnpackUtil.java │ │ └── CompressUtil.java └── test │ └── java │ └── com │ └── h2t │ └── study │ ├── BaseTest.java │ ├── CompressToolTest.java │ └── UnpackToolTest.java ├── .gitignore ├── README.md └── pom.xml /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/java/com/h2t/study/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class BaseTest { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/CompressUnpackApplication.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CompressUnpackApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CompressUnpackApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/enums/FileTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study.enums; 2 | 3 | /** 4 | * 压缩文件类型 5 | * 6 | * @author hetiantian 7 | * @version 1.0 8 | * @Date 2019/12/12 15:37 9 | */ 10 | public enum FileTypeEnum { 11 | TARGZ("tar.gz"), ZIP("zip"), RAR("rar"), GZ("gz"), TAR("tar"); 12 | private String typeName; 13 | 14 | FileTypeEnum(String typeName) { 15 | this.typeName = typeName; 16 | } 17 | 18 | public String getTypeName() { 19 | return typeName; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study.exception; 2 | 3 | /** 4 | * 自定义异常 5 | * 6 | * @author hetiantian 7 | * @version 1.0 8 | * @Date 2019/12/10 10:35 9 | */ 10 | public class CustomException extends RuntimeException { 11 | private String msg; 12 | 13 | public CustomException(String msg) { 14 | super(msg); 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "CustomException{" + 20 | "msg='" + msg + '\'' + 21 | '}'; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # compress-unpack 2 | 3 | ### compress-unpack介绍 4 | compress-unpack是文件、文件夹压缩解压工具类,可以支持压缩为如下格式: 5 | - rar 6 | - zip 7 | - tar.gz 8 | - tar 9 | 10 | ### rar格式的压缩与解压 11 | ### zip格式的压缩与解压 12 | ### tar.gz格式的压缩与解压 13 | - 压缩 14 | 对tar.gz的压缩分为三步: 15 | - 压缩为tar文件 16 | - 将tar文件压缩为gz 17 | - 删除tar文件 18 | - 解压 19 | 对tar.gz的解压分为三步: 20 | - 解压tar.gz为tar文件 21 | - 解压tar文件 22 | - 删除tar文件 23 | 24 | ### 解压缩工具类的使用 25 | **压缩、解压zip:** 26 | - 压缩 27 | ``` 28 | String sourcePath = "input/springboot-log"; 29 | String targetPath = "compress-output/"; 30 | CompressTool.compressToZip(sourcePath, targetPath); 31 | ``` 32 | - 解压 33 | ``` 34 | String sourcePath = "input/springboot-log.zip"; 35 | String targetPath = "unpack-output/"; 36 | File file = new File(sourcePath); 37 | UnpackTool.unpackZip(sourcePath, targetPath); 38 | ``` 39 | **压缩、解压rar:** 40 | - 解压 41 | ``` 42 | String sourcePath = "input/学习.rar"; 43 | String targetPath = "unpack-output/"; 44 | UnpackTool.unpackRar(sourcePath, targetPath); 45 | ``` 46 | **压缩、解压tar.gz:** 47 | - 解压 48 | ``` 49 | String sourcePath = "input/springboot-log.tar.gz"; 50 | String targetPath = "unpack-output/"; 51 | UnpackUtil.unpackTarGz(sourcePath, targetPath); 52 | ``` 53 | - 压缩 54 | ``` 55 | String sourcePath = "input/springboot-log"; 56 | String targetPath = "compress-output/"; 57 | CompressUtil.compressToTarGz(sourcePath, targetPath); 58 | ``` -------------------------------------------------------------------------------- /src/test/java/com/h2t/study/CompressToolTest.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study; 2 | 3 | import com.h2t.study.util.CompressUtil; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.io.IOException; 7 | 8 | /** 9 | * 压缩工具测试类 10 | * 11 | * @author hetiantian 12 | * @version 1.0 13 | * @Date 2019/12/11 11:48 14 | */ 15 | public class CompressToolTest extends BaseTest { 16 | /** 17 | * 压缩为zip测试 18 | */ 19 | @Test 20 | public void zipCompressTest() throws IOException { 21 | String sourcePath = "input/h2ttest"; 22 | String targetPath = "compress-output/"; 23 | CompressUtil.compressToZip(sourcePath, targetPath); 24 | } 25 | 26 | /** 27 | * 压缩为tar测试 28 | */ 29 | @Test 30 | public void tarCompressTest() throws IOException { 31 | String sourcePath = "input/springboot-log"; 32 | String targetPath = "compress-output/"; 33 | CompressUtil.compressToTar(sourcePath, targetPath); 34 | } 35 | 36 | /** 37 | * 压缩为gz测试 38 | */ 39 | @Test 40 | public void gzCompressTest() throws IOException { 41 | String sourcePath = "input/springboot-log.tar"; 42 | String targetPath = "compress-output/"; 43 | CompressUtil.compressTarToGz(sourcePath, targetPath); 44 | } 45 | 46 | /** 47 | * 压缩为tar.gz测试 48 | */ 49 | @Test 50 | public void tarGzCompressTest() { 51 | String sourcePath = "input/中文"; 52 | String targetPath = "G:/java工程/compress-unpack"; 53 | CompressUtil.compressToTarGz(sourcePath, targetPath); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/h2t/study/UnpackToolTest.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study; 2 | 3 | import com.h2t.study.util.UnpackUtil; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | /** 10 | * 解压工具类测试 11 | * 12 | * @author hetiantian 13 | * @version 1.0 14 | * @Date 2019/12/11 15:35 15 | */ 16 | public class UnpackToolTest extends BaseTest { 17 | /** 18 | * 解压zip测试 19 | */ 20 | @Test 21 | public void zipUnpackTest() throws IOException { 22 | String sourcePath = "1.zip"; 23 | String targetPath = "unpack-output/"; 24 | File file = new File(sourcePath); 25 | //方式一 26 | UnpackUtil.unpackZip(file, targetPath); 27 | //方式二 28 | UnpackUtil.unpackZip(sourcePath, targetPath); 29 | } 30 | 31 | /** 32 | * 解压rar测试 33 | */ 34 | @Test 35 | public void rarUnpackTest() throws Exception { 36 | String sourcePath = "input/算法SDK_2.rar"; 37 | String targetPath = "unpack-output"; 38 | File file = new File(sourcePath); 39 | //方式一 40 | UnpackUtil.unpackRar(sourcePath, targetPath); 41 | //方式二 42 | //UnpackUtil.unRar(file, targetPath); 43 | //UnpackUtil.RarFiles(sourcePath, targetPath); 44 | } 45 | 46 | /** 47 | * 解压tar.gz测试 48 | */ 49 | @Test 50 | public void tarGzUnpackTest() throws IOException { 51 | String sourcePath = "input/test.tar.gz"; 52 | String targetPath = "unpack-output/"; 53 | UnpackUtil.unpackTarGz(sourcePath, targetPath); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study.util; 2 | 3 | import com.h2t.study.exception.CustomException; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * 文件工具类 11 | * 12 | * @author hetiantian 13 | * @version 1.0 14 | * @Date 2019/12/12 11:14 15 | */ 16 | public class FileUtil { 17 | private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class); 18 | 19 | /** 20 | * 删除文件 21 | * 22 | * @param filePath 文件路径 23 | * @return 24 | */ 25 | public static boolean deleteFile(String filePath) { 26 | File file = new File(filePath); 27 | return deleteFile(file); 28 | } 29 | 30 | /** 31 | * 删除文件 32 | * 33 | * @param file 34 | * @return 35 | */ 36 | public static boolean deleteFile(File file) { 37 | if (!file.exists()) { 38 | LOGGER.error("the file is not exist, file name: {}", file.getName()); 39 | throw new CustomException("the file is not exist"); 40 | } 41 | 42 | return file.delete(); 43 | } 44 | 45 | /** 46 | * 源文件路径判断 47 | * 48 | * @param sourcePath 待解压文件路径 49 | * @return 50 | */ 51 | public static File validateSourcePath(String sourcePath) { 52 | File sourceFile = new File(sourcePath); 53 | if (!sourceFile.exists()) { 54 | LOGGER.error("the source file is not exist, source path: {}", sourceFile.getAbsolutePath()); 55 | throw new CustomException("the source file is not exist"); 56 | } 57 | return sourceFile; 58 | } 59 | 60 | /** 61 | * 解压路径存在判断 62 | * 63 | * @param targetPath 64 | * @return 65 | */ 66 | public static File validateTargetPath(String targetPath) { 67 | File targetFile = new File(targetPath); 68 | if (!targetFile.exists()) { 69 | LOGGER.info("the target file is not exist, target path: {}. create", targetFile.getAbsolutePath()); 70 | targetFile.mkdirs(); 71 | } 72 | 73 | return targetFile; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.2.RELEASE 9 | 10 | 11 | com.h2t.study 12 | compress-unpack 13 | 0.0.1-SNAPSHOT 14 | compress-unpack 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | org.junit.vintage 34 | junit-vintage-engine 35 | 36 | 37 | 38 | 39 | 40 | 41 | com.github.junrar 42 | junrar 43 | 4.0.0 44 | 45 | 46 | 47 | 48 | org.apache.commons 49 | commons-compress 50 | 1.19 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/util/UnpackUtil.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study.util; 2 | 3 | import com.github.junrar.Archive; 4 | import com.github.junrar.exception.RarException; 5 | import com.github.junrar.rarfile.FileHeader; 6 | import org.apache.commons.compress.archivers.tar.TarArchiveEntry; 7 | import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; 8 | import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; 9 | import org.apache.commons.compress.utils.IOUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.io.*; 14 | import java.util.Enumeration; 15 | import java.util.zip.ZipEntry; 16 | import java.util.zip.ZipFile; 17 | 18 | /** 19 | * 解缩工具类 20 | * 21 | * @author hetiantian 22 | * @version 1.0 23 | * @Date 2019/12/10 10:02 24 | */ 25 | public class UnpackUtil { 26 | private final static Logger LOGGER = LoggerFactory.getLogger(UnpackUtil.class); 27 | private static final int BUFFER_SIZE = 1024; 28 | 29 | /** 30 | * 解压zip格式的压缩包 31 | * 32 | * @param sourcePath 待解压文件路径 33 | * @param targetPath 解压路径 34 | */ 35 | public static void unpackZip(String sourcePath, String targetPath) { 36 | File sourceFile = FileUtil.validateSourcePath(sourcePath); 37 | unpackZip(sourceFile, targetPath); 38 | } 39 | 40 | public static void unpackZip(File sourceFile, String targetPath) { 41 | //校验解压地址是否存在 42 | FileUtil.validateTargetPath(targetPath); 43 | 44 | LOGGER.info("start to unpack zip file, file name:{}", sourceFile.getName()); 45 | long start = System.currentTimeMillis(); 46 | try (ZipFile zipFile = new ZipFile(sourceFile)) { 47 | Enumeration entries = zipFile.entries(); 48 | while (entries.hasMoreElements()) { 49 | ZipEntry entry = (ZipEntry) entries.nextElement(); 50 | // 如果是文件夹,就创建个文件夹 51 | if (entry.isDirectory()) { 52 | String dirPath = targetPath + File.separator + entry.getName(); 53 | File dir = new File(dirPath); 54 | dir.mkdirs(); 55 | } else { 56 | // 如果是文件,就先创建一个文件,然后用io流把内容copy过去 57 | File tempFile = new File(targetPath + File.separator + entry.getName()); 58 | // 保证这个文件的父文件夹必须要存在 59 | if (!tempFile.getParentFile().exists()) { 60 | tempFile.getParentFile().mkdirs(); 61 | } 62 | tempFile.createNewFile(); 63 | 64 | // 将压缩文件内容写入到这个文件中 65 | try (InputStream is = zipFile.getInputStream(entry); 66 | FileOutputStream fos = new FileOutputStream(tempFile)) { 67 | int len; 68 | byte[] buf = new byte[BUFFER_SIZE]; 69 | while ((len = is.read(buf)) != -1) { 70 | fos.write(buf, 0, len); 71 | } 72 | } 73 | } 74 | 75 | } 76 | LOGGER.info("finish unpack zip file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 77 | } catch (Exception e) { 78 | LOGGER.error("unpack zip throw exception:{}", e); 79 | } 80 | } 81 | 82 | /** 83 | * 解压rar格式的压缩包 84 | * 85 | * @param sourcePath 待解压文件 86 | * @param targetPath 解压路径 87 | */ 88 | public static void unpackRar(String sourcePath, String targetPath) { 89 | File sourceFile = FileUtil.validateSourcePath(sourcePath); 90 | unpackRar(sourceFile, targetPath); 91 | } 92 | 93 | public static void unpackRar(File sourceFile, String targetPath) { 94 | //校验解压地址是否存在 95 | FileUtil.validateTargetPath(targetPath); 96 | 97 | LOGGER.info("start to unpack rar file, file name:{}", sourceFile.getName()); 98 | long start = System.currentTimeMillis(); 99 | System.out.println("absolute path is ============= " + sourceFile.getAbsolutePath()); 100 | try (Archive archive = new Archive(new FileInputStream(sourceFile))) { 101 | FileHeader fileHeader = archive.nextFileHeader(); 102 | while (fileHeader != null) { 103 | //如果是文件夹 104 | if (fileHeader.isDirectory()) { 105 | fileHeader = archive.nextFileHeader(); 106 | continue; 107 | } 108 | 109 | //防止文件名中文乱码问题的处理 110 | File out = new File(String.format("%s%s%s", targetPath, File.separator, fileHeader.getFileNameW().isEmpty() ? fileHeader 111 | .getFileNameString() : fileHeader.getFileNameW())); 112 | 113 | if (!out.exists()) { 114 | if (!out.getParentFile().exists()) { 115 | out.getParentFile().mkdirs(); //相对路径可能多级,可能需要创建父目录. 116 | } 117 | out.createNewFile(); 118 | } 119 | try (FileOutputStream os = new FileOutputStream(out)) { 120 | archive.extractFile(fileHeader, os); 121 | } catch (RarException e) { 122 | LOGGER.error("unpack rar throw exception, filename:{}, e:{}", sourceFile.getName(), e); 123 | } 124 | fileHeader = archive.nextFileHeader(); 125 | } 126 | } catch (IOException | RarException e) { 127 | LOGGER.error("unpack rar throw exception, file name:{}, e:{}", sourceFile.getName(), e); 128 | } 129 | 130 | LOGGER.info("finish unpack rar file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 131 | } 132 | 133 | 134 | /** 135 | * 解压tar.gz格式的压缩包为tar压缩包 136 | * 137 | * @param sourcePath 待解压文件路径 138 | * @param targetPath 解压路径 139 | */ 140 | public static void unpackTarGz(String sourcePath, String targetPath) throws IOException { 141 | long start = System.currentTimeMillis(); 142 | FileUtil.validateSourcePath(sourcePath); 143 | File sourceFile = new File(sourcePath); 144 | LOGGER.info("start to unpack tar.gz file, file name:{}", sourceFile.getName()); 145 | 146 | try (FileInputStream fileInputStream = new FileInputStream(sourceFile); 147 | GzipCompressorInputStream gzipCompressorInputStream = new GzipCompressorInputStream(fileInputStream); 148 | TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipCompressorInputStream, "UTF-8")) { 149 | File targetFile = new File(targetPath); 150 | TarArchiveEntry entry; 151 | while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) { 152 | if (entry.isDirectory()) { 153 | continue; 154 | } 155 | 156 | File curFile = new File(targetFile, entry.getName()); 157 | File parent = curFile.getParentFile(); 158 | if (!parent.exists()) { 159 | parent.mkdirs(); 160 | } 161 | 162 | try (FileOutputStream outputStream = new FileOutputStream(curFile)) { 163 | IOUtils.copy(tarArchiveInputStream, outputStream); 164 | } 165 | } 166 | 167 | } 168 | LOGGER.info("finish unpack tar.gz file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/main/java/com/h2t/study/util/CompressUtil.java: -------------------------------------------------------------------------------- 1 | package com.h2t.study.util; 2 | 3 | import com.h2t.study.enums.FileTypeEnum; 4 | import org.apache.commons.compress.archivers.tar.TarArchiveEntry; 5 | import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; 6 | import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.io.*; 11 | import java.util.zip.CRC32; 12 | import java.util.zip.CheckedOutputStream; 13 | import java.util.zip.ZipEntry; 14 | import java.util.zip.ZipOutputStream; 15 | 16 | /** 17 | * 压缩工具类 18 | * 19 | * @author hetiantian 20 | * @version 1.0 21 | * @Date 2019/12/10 10:09 22 | */ 23 | public class CompressUtil { 24 | private static final int BUFFER = 1024; 25 | private final static Logger LOGGER = LoggerFactory.getLogger(CompressUtil.class); 26 | 27 | /** 28 | * 压缩为zip格式,支持文件、文件夹的压缩 29 | * 30 | * @param sourcePath 被压缩文件地址 31 | * @param targetPath 压缩文件保存地址 32 | */ 33 | public static void compressToZip(String sourcePath, String targetPath) { 34 | File sourceFile = FileUtil.validateSourcePath(sourcePath); 35 | compressToZip(sourceFile, targetPath); 36 | } 37 | 38 | /** 39 | * 压缩为zip格式,支持文件、文件夹的压缩 40 | * 41 | * @param sourceFile 被压缩文件 42 | * @param targetPath 压缩文件保存地址 43 | */ 44 | public static void compressToZip(File sourceFile, String targetPath) { 45 | FileUtil.validateTargetPath(targetPath); 46 | //输入文件路径包含文件名 47 | File targetFile = new File(String.format("%s%s%s.%s", targetPath, File.separator, sourceFile.getName(), FileTypeEnum.ZIP.getTypeName())); 48 | 49 | //1.使用try-with-resource优雅关闭流 50 | //2.使用CRC32进行文件校验 51 | LOGGER.info("start to compress file to zip, file name:{}", sourceFile.getName()); 52 | long start = System.currentTimeMillis(); 53 | try (FileOutputStream fileOut = new FileOutputStream(targetFile); 54 | CheckedOutputStream cos = new CheckedOutputStream(fileOut, new CRC32()); 55 | ZipOutputStream zipOut = new ZipOutputStream(cos)) { 56 | String baseDir = ""; 57 | compressToZip(sourceFile, zipOut, baseDir); 58 | } catch (FileNotFoundException e) { 59 | LOGGER.error("compress file to zip throw exception:{}", e); 60 | } catch (IOException e) { 61 | LOGGER.error("compress file to zip throw exception:{}", e); 62 | } 63 | LOGGER.info("finish compress file to zip, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 64 | } 65 | 66 | /** 67 | * 真正文件/文件夹的压缩部分 68 | * 69 | * @param sourceFile 待压缩文件 70 | * @param zipOut 压缩流 71 | * @param baseDir 72 | */ 73 | private static void compressToZip(File sourceFile, ZipOutputStream zipOut, String baseDir) throws IOException { 74 | //文件夹的压缩 75 | if (sourceFile.isDirectory()) { 76 | compressDirectoryToZip(sourceFile, zipOut, baseDir); 77 | } else { 78 | //文件的压缩 79 | compressFileToZip(sourceFile, zipOut, baseDir); 80 | } 81 | } 82 | 83 | /** 84 | * 文件夹的压缩 85 | * 86 | * @param sourceFile 待压缩文件 87 | * @param zipOut 压缩流 88 | * @param basePath 基本路径 89 | */ 90 | private static void compressDirectoryToZip(File sourceFile, ZipOutputStream zipOut, String basePath) throws IOException { 91 | File[] files = sourceFile.listFiles(); 92 | for (File file : files) { 93 | compressToZip(file, zipOut, basePath + sourceFile.getName() + File.separator); 94 | } 95 | } 96 | 97 | /** 98 | * 文件的压缩 99 | * 100 | * @param sourceFile 待压缩文件 101 | * @param zipOut 压缩流 102 | * @param basePath 基本路径 103 | */ 104 | private static void compressFileToZip(File sourceFile, ZipOutputStream zipOut, String basePath) throws IOException { 105 | if (!sourceFile.exists()) { 106 | return; 107 | } 108 | 109 | try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile))) { 110 | ZipEntry entry = new ZipEntry(basePath + sourceFile.getName()); 111 | zipOut.putNextEntry(entry); 112 | int count; 113 | byte data[] = new byte[BUFFER]; 114 | while ((count = bis.read(data, 0, BUFFER)) != -1) { 115 | zipOut.write(data, 0, count); 116 | } 117 | } 118 | } 119 | 120 | /** 121 | * 压缩为rar格式 122 | */ 123 | private static void compressRar() { 124 | } 125 | 126 | /** 127 | * 压缩为tar.gz格式 128 | * 129 | * @param sourcePath 130 | * @param targetPath 131 | */ 132 | public static void compressToTarGz(String sourcePath, String targetPath) { 133 | File sourceFile = new File(sourcePath); 134 | LOGGER.info("start to compress file to tar.gz, file name:{}", sourceFile.getName()); 135 | long start = System.currentTimeMillis(); 136 | //1.压缩为tar 137 | String rarSourcePath = compressToTar(sourcePath, targetPath); 138 | //2.压缩为gz 139 | compressTarToGz(rarSourcePath, targetPath); 140 | //3.删除tar 141 | if (!FileUtil.deleteFile(rarSourcePath)) { 142 | LOGGER.error("delete rar file field, rar file path:{}", rarSourcePath); 143 | } 144 | 145 | LOGGER.info("finish compress file to tar.gz, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 146 | } 147 | 148 | /** 149 | * 压缩格式为gz 150 | * 151 | * @param sourcePath tar文件路径 152 | * @param targetPath 压缩文件保存地址 153 | */ 154 | public static void compressTarToGz(String sourcePath, String targetPath) { 155 | File sourceFile = FileUtil.validateSourcePath(sourcePath); 156 | compressTarToGz(sourceFile, targetPath); 157 | } 158 | 159 | /** 160 | * 压缩格式为gz 161 | * 162 | * @param sourceFile tar文件路径 163 | * @param targetPath 压缩文件保存地址 164 | */ 165 | public static void compressTarToGz(File sourceFile, String targetPath) { 166 | //校验解压路径是否存在 167 | FileUtil.validateTargetPath(targetPath); 168 | LOGGER.info("start to compress tar file to tar.gz, file name:{}", sourceFile.getName()); 169 | long start = System.currentTimeMillis(); 170 | try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile))) { 171 | try (GzipCompressorOutputStream gos = new GzipCompressorOutputStream(new BufferedOutputStream( 172 | new FileOutputStream(String.format("%s%s%s.%s", 173 | targetPath, File.separator, sourceFile.getName(), FileTypeEnum.GZ.getTypeName()))))) { 174 | byte[] buffer = new byte[BUFFER]; 175 | int read; 176 | while ((read = bis.read(buffer)) != -1) { 177 | gos.write(buffer, 0, read); 178 | } 179 | } 180 | } catch (FileNotFoundException e) { 181 | e.printStackTrace(); 182 | } catch (IOException e) { 183 | e.printStackTrace(); 184 | } 185 | LOGGER.info("finish compress tar file to tar.gz, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 186 | } 187 | 188 | /** 189 | * 压缩为tar格式 190 | * 191 | * @param sourcePath 待压缩文件路径 192 | * @param targetPath 压缩文件保存地址 193 | * @return tar压缩文件路径 194 | */ 195 | public static String compressToTar(String sourcePath, String targetPath) { 196 | File sourceFile = FileUtil.validateSourcePath(sourcePath); 197 | //校验解压路径是否存在 198 | FileUtil.validateTargetPath(targetPath); 199 | 200 | File tarFile = new File(targetPath, String.format("%s.%s", sourceFile.getName(), FileTypeEnum.TAR.getTypeName())); 201 | LOGGER.info("start compress file to tar, file name:{}, cost:{} ms", sourceFile.getName()); 202 | long start = System.currentTimeMillis(); 203 | try (TarArchiveOutputStream tos = new TarArchiveOutputStream(new FileOutputStream(tarFile))) { 204 | tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); //解决长路径问题 205 | String base = sourceFile.getName(); 206 | if (sourceFile.isDirectory()) { 207 | compressDirectoryToTar(sourceFile, tos, base); 208 | } else { 209 | compressFileToTar(tos, sourceFile, base); 210 | } 211 | } catch (FileNotFoundException e) { 212 | e.printStackTrace(); 213 | } catch (IOException e) { 214 | e.printStackTrace(); 215 | } 216 | LOGGER.info("finish compress file to tar, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start); 217 | //返回tar压缩文件路径 218 | return tarFile.getAbsolutePath(); 219 | } 220 | 221 | /** 222 | * 文件夹压缩为tar包,本质递归文件压缩处理 223 | * 224 | * @param sourceFile 225 | * @param tos 226 | * @param basePath 基本路径 227 | */ 228 | private static void compressDirectoryToTar(File sourceFile, TarArchiveOutputStream tos, String basePath) { 229 | File[] files = sourceFile.listFiles(); 230 | for (File file : files) { 231 | if (file.isDirectory()) { 232 | compressDirectoryToTar(file, tos, String.format("%s%s%s", basePath, File.separator, file.getName())); 233 | } else { 234 | try { 235 | compressFileToTar(tos, file, basePath); 236 | } catch (IOException e) { 237 | e.printStackTrace(); 238 | } 239 | } 240 | } 241 | } 242 | 243 | /** 244 | * 文件压缩为tar包 245 | * 246 | * @param tos 247 | * @param sourceFile 248 | * @throws IOException 249 | */ 250 | private static void compressFileToTar(TarArchiveOutputStream tos, File sourceFile, String basePath) throws IOException { 251 | TarArchiveEntry tEntry = new TarArchiveEntry(String.format("%s%s%s", basePath, File.separator, sourceFile.getName())); 252 | tEntry.setSize(sourceFile.length()); 253 | tos.putArchiveEntry(tEntry); 254 | 255 | try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile))) { 256 | 257 | byte[] buffer = new byte[BUFFER]; 258 | int read; 259 | while ((read = bis.read(buffer)) != -1) { 260 | tos.write(buffer, 0, read); 261 | } 262 | } 263 | tos.closeArchiveEntry(); 264 | } 265 | } 266 | --------------------------------------------------------------------------------