实现服务器上的文件批量压缩成zip下载(可以根据需求自定义多个文件夹)

1.实现服务器上文件批量压缩成zip下载+自定义多个文件夹

package com.fn.szpd.service.impl.zczx;

import com.fn.common.constant.BusinessConstants;
import com.fn.common.core.domain.AjaxResult;
import com.fn.common.exception.base.BaseException;
import com.fn.szpd.domain.SzpdFile;
import com.fn.szpd.service.ISzpdFileService;
import lombok.RequiredArgsConstructor;
import org.apache.tomcat.util.http.fileupload.IOUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName: DownloadZip
 * @Author: lxh
 * @Description:
 * @Date: 2022/6/18 14:20
 */
@RequiredArgsConstructor
public class DownloadZip {

    private final ISzpdFileService fileService;
    /**
     * 个人中心-我的参赛-提报文件下载zip
     * @param response /
     * @param achievementId /
     * @return com.fn.common.core.domain.AjaxResult /
     * @author lxh
     * @date 2022/6/18 13:44
     */
    public AjaxResult downloadZip(HttpServletResponse response, Long achievementId) {
        try {
            if (achievementId == null) {
                throw new BaseException("成果id不能为空");
            }
            //获取要下载的文件列表
            SzpdFile szpdFile = new SzpdFile();
            szpdFile.setEntityId(achievementId);
            szpdFile.setFileType(BusinessConstants.FILE_TYPE_FJ);
            szpdFile.setBusinessType(BusinessConstants.BUSINESS_TYPE_SZPD_ZCZX_ACHIEVEMENT);
            List<SzpdFile> fileList = fileService.selectSzpdFileList(szpdFile);
            if (0 == fileList.size()) {
                throw new BaseException("当前成果没有附件");
            }
            Map<Long, List<SzpdFile>> listMap = fileList.stream().collect(Collectors.groupingBy(SzpdFile::getId));
            if (listMap.isEmpty()) {
                throw new BaseException("当前成果没有附件");
            }
            // 创建临时路径,存放压缩文件
            String zipFilePath = System.getProperty("user.dir") + File.separator + "downloadZip" + File.separator;
            System.out.println("临时文件路径"+zipFilePath);
            File zipFile = new File(zipFilePath);
            if (!zipFile.exists()) {
                zipFile.mkdirs();
            }
            String temporaryZipName = zipFilePath + "临时存放.zip";
            File zipFiles = new File(temporaryZipName);
            if (!zipFiles.exists()) {
                zipFiles.createNewFile();
            }
            // 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(temporaryZipName));
            for (Map.Entry<Long, List<SzpdFile>> entry : listMap.entrySet()) {
                writingFilesToZip(zipFilePath, zipOut, entry);
            }
            // 压缩完成后,关闭压缩流
            zipOut.close();
            // 拼接下载默认名称并转为ISO-8859-1格式
            response.setHeader("Content-Disposition", "attachment;filename=" + new String((achievementId + ".zip").getBytes(), StandardCharsets.ISO_8859_1));
            // 该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
            response.setCharacterEncoding("UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream inputStream = new FileInputStream(temporaryZipName);
            // copy方法为文件复制,在这里直接实现了下载效果
            IOUtils.copy(inputStream, outputStream);
            // 关闭输入流
            inputStream.close();
            // 下载完成之后,删掉zip临时文件
            File fileTempZip = new File(zipFilePath);
            deleteDir(fileTempZip);
            return AjaxResult.success("下载成功");
        } catch (Exception e) {
            return AjaxResult.error("下载失败");
        }
    }

    /**
     * 文件写入压缩包
     *
     * @param zipFilePath:文件路径
     * @param zipOut:压缩文件输出流
     * @param entry:数据集合
     * @throws IOException:异常
     */
    private void writingFilesToZip(String zipFilePath, ZipOutputStream zipOut, Map.Entry<Long, List<SzpdFile>> entry) throws IOException {
        for (SzpdFile szpdFile : entry.getValue()) {
            downLoadFromUrl(szpdFile.getFileUrl(), zipFilePath, szpdFile.getFileName());
            byte[] buf = new byte[2 * 1024];
            String srcDir = zipFilePath + szpdFile.getFileName();
            File sourceFile = new File(srcDir);
            if (844 == entry.getKey()) {
                zipOut.putNextEntry(new ZipEntry(this.getFolderName(entry.getKey()) + File.separator + szpdFile.getFileName() + File.separator + sourceFile.getName()));
            } else {
                zipOut.putNextEntry(new ZipEntry(this.getFolderName(entry.getKey()) + File.separator + sourceFile.getName()));
            }
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zipOut.write(buf, 0, len);
            }
            zipOut.closeEntry();
            in.close();
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     * If a deletion fails, the method stops attempting to
     * delete and returns "false".
     */
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            assert children != null;
            //递归删除目录中的子目录下
            for (String child : children) {
                boolean success = deleteDir(new File(dir, child));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    /**
     * 通过url,将文件下载到本地
     *
     * @param urlStr:文件路径
     * @param savePath:保存地址
     * @param fileName:文件名称
     * @throws IOException:异常
     */
    public static void downLoadFromUrl(String urlStr, String savePath, String fileName) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为10秒
        conn.setConnectTimeout(10 * 1000);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");
        //得到返回的header
        Map<String, List<String>> map = conn.getHeaderFields();
        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);
        //文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        //写入文件
        fos.write(getData);
        fos.close();
        inputStream.close();
    }

    /**
     * 输入流转二进制
     *
     * @param inputStream:输入流
     * @return 二进制数组
     * @throws IOException:异常
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 根据资料类型获取其中文名称
     *
     * @param dataType:资料类型
     * @return 资料类型中文名称
     */
    public String getFolderName(Long dataType) {
        String result;
        if (dataType == 844) {
            result = "订单资料";
        } else if (dataType == 845) {
            result = "零件资料";
        } else {
            result = "";
        }
        return result;
    }
}

1.实现服务器上文件批量压缩成zip下载不定义文件夹

package com.fn.szpd.service.impl.zczx;

import com.fn.common.constant.BusinessConstants;
import com.fn.common.core.domain.AjaxResult;
import com.fn.common.exception.base.BaseException;
import com.fn.szpd.domain.SzpdFile;
import com.fn.szpd.service.ISzpdFileService;
import lombok.RequiredArgsConstructor;
import org.apache.tomcat.util.http.fileupload.IOUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName: DownloadZip
 * @Author: lxh
 * @Description:
 * @Date: 2022/6/18 14:20
 */
@RequiredArgsConstructor
public class DownloadZip {

    private final ISzpdFileService fileService;
    /**
     * 个人中心-我的参赛-提报文件下载zip
     * @param response /
     * @param achievementId /
     * @return com.fn.common.core.domain.AjaxResult /
     * @author lxh
     * @date 2022/6/18 13:44
     */
    public AjaxResult downloadZip(HttpServletResponse response, Long achievementId) {
        try {
            if (achievementId == null) {
                throw new BaseException("成果id不能为空");
            }
            //获取要下载的文件列表
            SzpdFile szpdFile = new SzpdFile();
            szpdFile.setEntityId(achievementId);
            szpdFile.setFileType(BusinessConstants.FILE_TYPE_FJ);
            szpdFile.setBusinessType(BusinessConstants.BUSINESS_TYPE_SZPD_ZCZX_ACHIEVEMENT);
            List<SzpdFile> fileList = fileService.selectSzpdFileList(szpdFile);
            if (0 == fileList.size()) {
                throw new BaseException("当前成果没有附件");
            }
            // 创建临时路径,存放压缩文件
            String zipFilePath = System.getProperty("user.dir") + File.separator + "downloadZip" + File.separator;
            System.out.println("临时文件路径"+zipFilePath);
            File zipFile = new File(zipFilePath);
            if (!zipFile.exists()) {
                zipFile.mkdirs();
            }
            String temporaryZipName = zipFilePath + "临时存放.zip";
            File zipFiles = new File(temporaryZipName);
            if (!zipFiles.exists()) {
                zipFiles.createNewFile();
            }
            // 压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(temporaryZipName));
            writingFilesToZip(zipFilePath, zipOut, fileList);
            // 压缩完成后,关闭压缩流
            zipOut.close();
            // 拼接下载默认名称并转为ISO-8859-1格式
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(("成果文件.zip").getBytes(), StandardCharsets.ISO_8859_1));
            // 该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
            response.setCharacterEncoding("UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream inputStream = new FileInputStream(temporaryZipName);
            // copy方法为文件复制,在这里直接实现了下载效果
            IOUtils.copy(inputStream, outputStream);
            // 关闭输入流
            inputStream.close();
            // 下载完成之后,删掉zip临时文件
            File fileTempZip = new File(zipFilePath);
            deleteDir(fileTempZip);
            return AjaxResult.success("下载成功");
        } catch (Exception e) {
            return AjaxResult.error("下载失败");
        }
    }

    /**
     * 文件写入压缩包
     *
     * @param zipFilePath:文件路径
     * @param zipOut:压缩文件输出流
     * @throws IOException:异常
     */
    private void writingFilesToZip(String zipFilePath, ZipOutputStream zipOut, List<SzpdFile> fileList) throws IOException {
        for (SzpdFile szpdFile : fileList) {
            downLoadFromUrl(szpdFile.getFileUrl(), zipFilePath, szpdFile.getFileName());
            byte[] buf = new byte[2 * 1024];
            String srcDir = zipFilePath + szpdFile.getFileName();
            File sourceFile = new File(srcDir);
            zipOut.putNextEntry(new ZipEntry(sourceFile.getName()));
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zipOut.write(buf, 0, len);
            }
            zipOut.closeEntry();
            in.close();
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     * If a deletion fails, the method stops attempting to
     * delete and returns "false".
     */
    private static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            assert children != null;
            //递归删除目录中的子目录下
            for (String child : children) {
                boolean success = deleteDir(new File(dir, child));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    /**
     * 通过url,将文件下载到本地
     *
     * @param urlStr:文件路径
     * @param savePath:保存地址
     * @param fileName:文件名称
     * @throws IOException:异常
     */
    public static void downLoadFromUrl(String urlStr, String savePath, String fileName) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为10秒
        conn.setConnectTimeout(10 * 1000);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");
        //得到返回的header
        Map<String, List<String>> map = conn.getHeaderFields();
        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);
        //文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        //写入文件
        fos.write(getData);
        fos.close();
        inputStream.close();
    }

    /**
     * 输入流转二进制
     *
     * @param inputStream:输入流
     * @return 二进制数组
     * @throws IOException:异常
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值