Loading

压缩工具-ZipUtil

介绍:提供了两个压缩方法
1、压缩指定文件夹
2、根据文件列表压缩
代码实现:

/*
 * 打工人的学习代码...
 */
package com.mybatis.tool.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 * <B>Description: Zip工具</B>
 * </P>
 * Revision Trail: (Date/Author/Description)
 * 2024/4/26 Ryan Huang CREATE
 *
 * @author Ryan Huang
 * @version 1.0
 */
public class ZipUtil {

    private static final Logger logger = LoggerFactory.getLogger(ZipUtil.class);

    private static final int  BUFFER_SIZE = 2 * 1024;


    /**
     * 压缩文件
     * @param srcDir 源目录
     * @param outputStream 输出流
     * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败
     */
    public static void toZip(String srcDir, OutputStream outputStream, boolean keepDirStructure){
        long startTime = System.currentTimeMillis();
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
            File sourceFile = new File(srcDir);
            compress(sourceFile, zipOutputStream, sourceFile.getName(), keepDirStructure);
            long endTime = System.currentTimeMillis();
            logger.info("压缩完成,耗时:{}ms", endTime - startTime);
        }catch (Exception e){
            logger.error("zip error", e);
            throw new RuntimeException("zip error");
        }
    }

    /**
     * 压缩文件
     * @param srcFileList 源文件列表
     * @param outputStream 输出流
     */
    public static void toZip(List<File> srcFileList, OutputStream outputStream){
        long startTime = System.currentTimeMillis();
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
            for (File file : srcFileList) {
                byte[] buf = new byte[BUFFER_SIZE];
                zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
                int len;
                try (FileInputStream fileInputStream = new FileInputStream(file)) {
                    while ((len = fileInputStream.read(buf)) != -1) {
                        zipOutputStream.write(buf, 0, len);
                    }
                }catch (IOException e){
                    logger.error("zip error", e);
                    throw new RuntimeException("zip error");
                }
                zipOutputStream.closeEntry();
            }
            long endTime = System.currentTimeMillis();
            logger.info("压缩完成,耗时:{}ms", endTime - startTime);
        }catch (Exception e){
            logger.error("zip error", e);
            throw new RuntimeException("zip error");
        }
    }

    /**
     * 递归压缩方法
     * @param sourceFile 源文件
     * @param zipOutputStream 压缩输出流
     * @param name 压缩后的名称
     * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zipOutputStream, String name, boolean keepDirStructure) throws Exception{
        byte[] buf = new byte[BUFFER_SIZE];
        if(sourceFile.isFile()){
            zipOutputStream.putNextEntry(new ZipEntry(name));
            int len;
            FileInputStream inputStream = new FileInputStream(sourceFile);
            while ((len = inputStream.read(buf)) != -1){
                zipOutputStream.write(buf, 0, len);
            }
            zipOutputStream.closeEntry();
            inputStream.close();
        }else{
            File[] fileList = sourceFile.listFiles();
            if(fileList == null || fileList.length == 0){
                //需保留原来的文件结构时,需要对空文件夹进行处理
                if(keepDirStructure){
                    zipOutputStream.putNextEntry(new ZipEntry(name + "/"));
                    zipOutputStream.closeEntry();
                }
            }else{
                for(File file : fileList){
                    if(keepDirStructure) {
                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                        compress(file, zipOutputStream, name + "/" + file.getName(), keepDirStructure);
                    }else {
                        compress(file, zipOutputStream, file.getName(), keepDirStructure);
                    }
                }
            }
        }
    }
}

posted @ 2024-04-26 16:31  IamHzc  阅读(116)  评论(0编辑  收藏  举报