Java实现将文件及其文件夹压缩成zip【完整工具类】

ZipUtils

package com.yrx.utils;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author: zjx
 * @Date: 14:34 2022-11-15
 * @Description ZIP工具类
 */
@Slf4j
public class ZipUtils {

    public static final String ZIP_SUFFIX = ".zip";

    private static final int BUFFER_SIZE = 2 * 1024;


    /**
     * 根据资源文件夹,目标文件夹,文件名打包成zip文件下载
     *
     * @param filePath
     * @param zipPath
     * @param name
     * @param response
     */
    public static void saveZip(String filePath, String zipPath, String name, HttpServletResponse response) {
        log.info("开始压缩" + System.currentTimeMillis());
        File zipFile = new File(zipPath + name + ZIP_SUFFIX);
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
            File[] files = new File(filePath).listFiles();
            byte[] buffer = new byte[1024];
            for (File file : files) {
                try (FileInputStream fis = new FileInputStream(file);) {
                    zos.putNextEntry(new ZipEntry(file.getName()));
                    int len;
                    //读入需要下载的文件的内容,打包到zip文件
                    while ((len = fis.read(buffer)) != -1) {
                        zos.write(buffer, 0, len);
                    }
                    zos.flush();
                    zos.closeEntry();
                } catch (Exception e) {
                    log.info("出现异常", e);
                }

            }
            zos.close();
            log.info("压缩结束" + System.currentTimeMillis());
            log.info("开始下载" + System.currentTimeMillis());
            FileUtils.downloadZip1(zipFile, response);
            log.info("结束下载" + System.currentTimeMillis());
            FileUtils.deleteDir(filePath);
            FileUtils.deleteDir(zipPath);
        } catch (Exception e) {
            log.info("出现异常", e);
        }
    }

    /**
     * 压缩成ZIP 方法1
     *
     * @param filePath         压缩文件夹路径
     * @param zipPath          压缩文件保存路径
     * @param name             压缩包名称
     * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void fileToZip(String filePath, String zipPath, String name, boolean keepDirStructure, HttpServletResponse response) throws RuntimeException {
        log.info("开始压缩" + System.currentTimeMillis());
        File zipFile = new File(zipPath + name + ZIP_SUFFIX);
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()));
            File sourceFile = new File(filePath);
            compress(sourceFile, zos, name, keepDirStructure);
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("压缩完成,耗时:" + (System.currentTimeMillis() - start) + " ms");
        log.info("开始下载" + (System.currentTimeMillis() - start) + " ms");
        FileUtils.downloadZip1(zipFile, response);
        log.info("结束下载" + (System.currentTimeMillis() - start) + " ms");
        FileUtils.deleteDir(filePath);
        FileUtils.deleteDir(zipPath);
    }

    /**
     * 压缩成ZIP 方法2
     *
     * @param srcFiles 需要压缩的文件列表
     * @param out      压缩文件输出流
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[BUFFER_SIZE];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 递归压缩方法
     *
     * @param sourceFile       源文件
     * @param zos              zip输出流
     * @param name             压缩后的名称
     * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
     *                         false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean keepDirStructure) throws Exception {
        byte[] buf = new byte[BUFFER_SIZE];
        if (sourceFile.isFile()) {
            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                if (keepDirStructure) {
                    // 空文件夹的处理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 没有文件,不需要文件的copy
                    zos.closeEntry();
                }

            } else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构
                    if (keepDirStructure) {
                        // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
                        // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
                        compress(file, zos, name + "/" + file.getName(), keepDirStructure);
                    } else {
                        compress(file, zos, file.getName(), keepDirStructure);
                    }

                }
            }
        }
    }

}

FileUtils

package com.yrx.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @description: 文件工具类
 * @author: chenmet
 * @create: 2019/01/10 10:07
 */
@Slf4j
public class FileUtils {

   
    /**
     * 下载zip包
     *
     * @param file
     * @param response
     * @return
     */
    public static HttpServletResponse downloadZip1(File file, HttpServletResponse response) {
        try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream toClient = new BufferedOutputStream(response.getOutputStream())) {
            // 以流的形式下载文件。
            // 清空response
            response.reset();
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setContentType("application/octet-stream");
            //如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            IOUtils.copy(fis, toClient);
        } catch (IOException ex) {
            log.info("出现异常", ex);
        }
        return response;
    }

    /**
     * 删除目录下所有文件
     *
     * @param path
     * @return
     */
    public static boolean deleteDir(String path) {
        File file = new File(path);
        //判断是否待删除目录是否存在
        if (!file.exists()) {
            log.info("The dir are not exists!");
            return false;
        }
        String[] content = file.list();//取得当前目录下所有文件和文件夹
        if (null == content) {
            log.info("当前目录下没有可删除的文件");
        }
        for (String name : content) {
            File temp = new File(path, name);
            //判断是否是目录
            if (temp.isDirectory()) {
                deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
                temp.delete();//删除空目录
            } else {
                if (!temp.delete()) {//直接删除文件
                    log.info("The dir are not exists!");
                }
            }
        }
        //删除当前目录
        if (!file.delete()) {
            log.info("删除当前目录失败");
        }
        return true;
    }


}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java后端开发中,可以使用Java自带的工具类来处理压缩文件。其中,java.util.zip包提供了ZipOutputStream类,专门用于对文件进行压缩操作。通过使用ZipOutputStream类,我们可以将文件文件夹压缩成一个zip文件。 使用ZipOutputStream类进行压缩文件的操作步骤如下: 1. 创建一个ZipOutputStream对象,指定要输出的文件流。 2. 使用putNextEntry方法创建一个新的ZipEntry对象,指定要压缩的文件文件夹的路径。 3. 使用BufferedInputStream读取要压缩的文件文件夹的内容,并使用ZipOutputStream的write方法将内容写入压缩文件。 4. 循环执行步骤2和步骤3,直到所有要压缩的文件文件夹都被处理完毕。 5. 关闭ZipOutputStream对象,完成压缩操作。 下面是一个示例代码,展示了如何使用JavaZipOutputStream类进行文件压缩操作: ```java import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipUtils { public static void compressFile(String sourceFilePath, String zipFilePath) throws IOException { File sourceFile = new File(sourceFilePath); FileOutputStream fos = new FileOutputStream(zipFilePath); ZipOutputStream zos = new ZipOutputStream(fos); compress(sourceFile, zos, ""); zos.close(); fos.close(); } private static void compress(File file, ZipOutputStream zos, String parentPath) throws IOException { if (file.isDirectory()) { // 如果是文件夹,则递归处理子文件夹文件 File[] files = file.listFiles(); for (File subFile : files) { compress(subFile, zos, parentPath + file.getName() + "/"); } } else { // 如果是文件,则压缩文件 FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值