Java实现批量打包文件Zip下载(适用于Windows,Linux)

前言

     1.思路总结:
     * 1.每个单号多个文件直接遍历IO临时单号zip包,
     * 2.多个单号临时zip包遍历IO到总临时zip包,
     * 3.总临时zip包copy到前端下载zip包,
     * 4.删除所有临时zip包,下载完成!
     
     2. 参数说明:
     * AcasConfig.getProfile() 自定义的路径 D:/home/acas/uploadPath
     * totalZip:总临时zip包
     * zipList:多个临时订单zip包集合
     * zipFilePath:当前订单临时zip
     * paths:文件路径数组

目录

1.RestController层

2.Service层

3.批量下载,zip打包效果(示例:Windows版,linux也一样)


1.RestController层

/**本方法使用windows,Linux 批量下载,zip打包  实测用于生产环境
     * 通过订单id批量下载
     * @param ids 货号单集合
     * @return
     * 思路总结:
     * 1.每个单号多个文件直接遍历IO临时单号zip包,
     * 2.多个单号临时zip包遍历IO到总临时zip包,
     * 3.总临时zip包copy到前端下载zip包,
     * 4.删除所有临时zip包,下载完成!
     * 参数说明:
     * AcasConfig.getProfile() 自定义的路径 D:/home/acas/uploadPath
     * totalZip:总临时zip包
     * zipList:多个临时订单zip包集合
     * zipFilePath:当前订单临时zip
     * paths:文件路径数组
     */

@Api(tags = "订单表")
@RestController
@RequestMapping("/order/order")
@Slf4j
public class OrderController extends BaseController {
    @Autowired
    private IOrderService orderService;
    @Autowired
    private OrderMapper orderMapper;

    /**本方法使用windows,Linux 批量下载,zip打包  实测用于生产环境
     *
     * 通过订单id批量下载
     * @param ids 货号单集合
     * @return
     *
     * 思路总结:
     * 1.每个单号多个文件直接遍历IO临时单号zip包,
     * 2.多个单号临时zip包遍历IO到总临时zip包,
     * 3.总临时zip包copy到前端下载zip包,
     * 4.删除所有临时zip包,下载完成!
     *
     * 参数说明:
     * AcasConfig.getProfile() 自定义的路径 D:/home/acas/uploadPath
     * totalZip:总临时zip包
     * zipList:多个临时订单zip包集合
     * zipFilePath:当前订单临时zip
     * paths:文件路径数组
     */
    @ApiOperation(value = "通过订单id批量下载", notes = "通过订单id批量下载")
    @GetMapping(value = "/batchDownload")
    public AjaxResult batchDownload(@RequestParam String ids, HttpServletResponse response) {
        //批量下载订单号单如 ids:"MA2206280160900002,MA2206280003500001,MA2206280003500002,MA2206280003500003"
        String[] parameterValues = ids.split(",");
        //各个文件压缩包临时存放路径集合
        List<String> zipList = new ArrayList();
        //Linux版创建临时zip,总存放压缩文件   AcasConfig.getProfile()= D:/home/acas/uploadPath/临时zip.zip
        String totalZip = AcasConfig.getProfile() + "/临时zip.zip";
        try {
            for (String orderNo : parameterValues) {
                //通过遍历订单号获取所有这一订单所有数据库中的文件路径 resultOriginFile:"/profile/upload/2022/05/23/85e2fbc8-6a3e-4544-8a88-97b9febb1ddd粗蛋白.jpg,/profile/upload/2022/05/23/e52773f6-7fae-4c36-97c5-b9edfbea2dc3粗脂肪.jpg"
                String resultOriginFile = orderMapper.selectOrder(orderNo).getResultOriginFile();
                if (StringUtils.isEmpty(resultOriginFile)) {
                    continue;
                }
                //Linux版创建临时文件
                String zipFilePath = AcasConfig.getProfile() + "/" + orderNo + "订单zip.zip";
                zipList.add(zipFilePath);
                //文件路径数组 paths :["/profile/upload/2022/05/23/85e2fbc8-6a3e-4544-8a88-97b9febb1ddd粗蛋白.jpg","/profile/upload/2022/05/23/e52773f6-7fae-4c36-97c5-b9edfbea2dc3粗脂肪.jpg"]
                String[] paths = resultOriginFile.split(",");
                //调用@Service层方法
                orderService.batchDownload(totalZip, zipList, zipFilePath, paths);
            }
            //判断有无订单需要下载文件,没有直接相应前台"没有需要下载的文件!",直接结束方法
            if (CollectionUtils.isEmpty(zipList)) {
                return AjaxResult.error("没有需要下载的文件!");
            }
            // 设置Content-Disposition响应头,控制浏览器弹出保存框,若没有此句浏览器会直接打开并显示文件
            // 中文名要进行URLEncoder.encode编码,否则客户端能下载但名字会乱码
            String orderDocuments = "订单原始记录文件.zip";
            String filenames = URLEncoder.encode(orderDocuments, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + filenames + ";" + "filename*=utf-8''" + filenames);
            //该流不可以手动关闭,手动关闭下载会出问题,下载完成后会自动关闭
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream inputStream = new FileInputStream(totalZip);
            // 如果是SpringBoot框架,在这个路径 需要org.apache.tomcat.util.http.fileupload.IOUtils产品否则,需要自主引入apache的 commons-io依赖
            // copy方法为文件复制,在这里直接实现了下载效果
            IOUtils.copy(inputStream, outputStream);
            inputStream.close();
            //下载完成之后,删掉临时zip包
            zipList.add(totalZip);
            for (String zipListPath : zipList) {
                File fileTempZip = new File(zipListPath);
                fileTempZip.delete();
            }
        } catch (Exception e) {
            log.error("下载异常!", e);
            return AjaxResult.error("下载异常!");
        }
        return AjaxResult.success("下载完成!");
    }

}

2.Service层

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Override
    public void batchDownload(String totalZip, List<String> zipList, String zipFilePath, String[] paths) throws IOException {
        //Linux不会自动创建,手动创建临时的.zip文件
        File totalFile = new File(totalZip);
        if (!totalFile.exists()) {
            totalFile.createNewFile();
        }

        File zipFile = new File(zipFilePath);
        if (!zipFile.exists()) {
            zipFile.createNewFile();
        }
        if (paths.length != 0) {
            //压缩输出流,包装流,将临时文件输出流包装成压缩流,将所有文件输出到这里,打成zip包
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath));
            ZipOutputStream totalZipOut = new ZipOutputStream(new FileOutputStream(totalZip));
            //循环调用压缩文件方法,将一个一个需要下载的文件打入压缩文件包
            for (String path : paths) {
                //文件完整路径
                String pathFile = path.replaceAll("/profile", "");
                path = AcasConfig.getProfile() + pathFile;
                //调用压缩方法在下面定义
                fileToZip(path, zipOut);
            }
            zipOut.close();
            //循环调用压缩文件方法,将一个一个压缩包打入总压缩文件包
            for (String zipListPath : zipList) {
                fileToZip(zipListPath, totalZipOut);
            }
            totalZipOut.close();
        }
    }

    private static void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {
        // 需要压缩的文件
        File file = new File(filePath);
        // 获取文件名称,如果有特殊命名需求,可以将参数列表拓展,传fileName
        String documents = file.getName();
        FileInputStream fileInput = new FileInputStream(filePath);
        // 缓冲
        byte[] bufferArea = new byte[1024 * 10];
        BufferedInputStream bufferStream = new BufferedInputStream(fileInput, 1024 * 10);
        // 将当前文件作为一个zip实体写入压缩流,fileName代表压缩文件中的文件名称
        zipOut.putNextEntry(new ZipEntry(documents));
        int length = 0;
        // 最常规IO操作,不必紧张
        while ((length = bufferStream.read(bufferArea, 0, 1024 * 10)) != -1) {
            zipOut.write(bufferArea, 0, length);
        }
        //关闭流
        fileInput.close();
        // 需要注意的是缓冲流必须要关闭流,否则输出无效
        bufferStream.close();
        // 压缩流不必关闭,使用完后再关
    }
}

3.批量下载,zip打包效果(示例:Windows版,linux也一样)

 我也是第一次接触批量下载,它本身并不难,都只是一些IO的常规操作,没有弯弯绕绕,只是在实现完整功能的过程中踩到了一些坑,在此记录一下,以便加深印象和帮助他人吧~~

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java实现批量下载并将文件打包ZIP格式,可以使用java.util.zip包提供的类和方法。以下是一个简单的实现示例: 首先,需要准备一个文件列表,包含要下载文件的路径。可以通过手动指定路径,或者通过程序动态获取,具体根据需求而定。 接下来,需要使用java.util.zip包中的ZipOutputStream类和FileInputStream类来实现文件打包。可以创建一个空的ZipOutputStream对象,并使用FileInputStream读取每个文件,然后将其添加到ZipOutputStream中。最后,关闭ZipOutputStream。 同时,还需要使用java.net包中的URL和URLConnection类来进行文件下载。可以为每个需要下载文件创建一个URL对象,打开URLConnection连接并获取其输入流。然后,将输入流传递给FileOutputStream,使用java.io包中的FileOutputStream类将文件下载到本地。 以下是一个简单的示例代码: import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipDownloader { public static void main(String[] args) { List<String> fileList = getListOfFiles(); // 获取文件列表,具体根据需求实现 String zipFileName = "downloadedFiles.zip"; // 设定打包后的ZIP文件名 try { FileOutputStream fos = new FileOutputStream(zipFileName); ZipOutputStream zos = new ZipOutputStream(fos); for (String file : fileList) { URL url = new URL(file); URLConnection connection = url.openConnection(); InputStream is = connection.getInputStream(); zos.putNextEntry(new ZipEntry(file)); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { zos.write(buffer, 0, length); } is.close(); } zos.closeEntry(); zos.close(); System.out.println("文件下载打包ZIP完成。"); } catch (IOException e) { e.printStackTrace(); } } } 需要注意的是,该示例只是一个简单的实现,并没有处理异常情况,如文件不存在、网络连接失败等。在实际应用中,需要对这些异常进行适当的处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值