• 批量打包成ZIP压缩文件


    一、前言

      在开发的过程中,我们有时候会遇到提供数据下载的功能,当数据量较大的时候,可能需要分开几个文件,然后再在后台打包成ZIP压缩文件,传送到前台。之前博客中有提及过如何用Java实现添加到压缩文件中,当时只讨论了如何单个文件添加压缩文件,这篇文章将讨论多文件压缩的问题。

    二、多文件压缩

        @Test
        public void test() throws Exception{
            // 被压缩文件
            File file = new File("C:\Users\Administrator\Desktop\文件a.pdf");
            File file2 = new File("C:\Users\Administrator\Desktop\文件b.pdf");
    
            // 输出文件outputStream
            File outFile = new File("C:\Users\Administrator\Desktop\压缩文件.zip");
            FileOutputStream outputStream = new FileOutputStream(outFile);
            ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
    
            // 读取file文件
            FileInputStream inputStream = new FileInputStream(file);
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(bytes);
            zipOutputStream.flush();
    
            // 读取file2文件
            inputStream = new FileInputStream(file2);
            bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            zipEntry = new ZipEntry(file2.getName());
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(bytes);
            zipOutputStream.flush();
    
            // 关闭各种流
            zipOutputStream.closeEntry();
            inputStream.close();
            zipOutputStream.close();
            outputStream.close();
    
        }

      上述这段代码,可以实现两个文件添加到ZIP压缩文件中。这种面相过程的写法,在某种程度上符合人的思考逻辑与顺序。但这种写法代码的耦合性高,代码复用性差。不是像上述代码那样写死,而是需要到本地文件中去取,又或者从数据库中拿,还是用POI读取Excel的方式获取文件路径,都不太好处理。人为操作的依赖性强。

    三、基于面相对象多文件添加ZIP文件

        /**
         * 文件读取缓冲区大小
         */
        private static final int CACHE_SIZE = 1024;
    
        @Test
        public void test2() throws Exception{
            // 获取文件列表
            List<File> fileList = this.getFileList();
            // 压缩到ZIP文件中
            this.toZIP(fileList);
        }
    
        /**
         * 获取文件列表
         * @return
         */
        private List<File> getFileList(){
            List<File> fileList = new ArrayList<>();
            File file = new File("C:\Users\Administrator\Desktop\文件a.pdf");
            File file2 = new File("C:\Users\Administrator\Desktop\文件b.pdf");
            fileList.add(file);
            fileList.add(file2);
            return fileList;
        }
    
        /**
         * 压缩到ZIP文件中
         * @param fileList
         * @throws Exception
         */
        private void toZIP(List<File> fileList) throws Exception{
            // 定义读取问价及读取数组
            FileInputStream inputStream = null;
            byte[] bytes = null;
    
            // 输出文件outputStream
            File outFile = new File("C:\Users\Administrator\Desktop\压缩文件.zip");
            FileOutputStream outputStream = new FileOutputStream(outFile);
            ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
    
            // 循环写入ZIP文件
            for(File file : fileList){
                // 定义实体
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                // 将文件读到数组中
                inputStream = new FileInputStream(file);
                // 整体读到内存(文件过大会内存溢出)
                //bytes = new byte[inputStream.available()];
                //inputStream.read(bytes);
                //zipOutputStream.write(bytes);
                // 分批读写
                bytes = new byte[CACHE_SIZE];
                int len = 0;
                while((len = inputStream.read(bytes)) != -1){
                    zipOutputStream.write(bytes);
                }
                zipOutputStream.flush();
            }
            // 关闭各种流
            zipOutputStream.closeEntry();
            inputStream.close();
            zipOutputStream.close();
            outputStream.close();
        }

       该断代码中,重新划分获取文件的模块,同时增加的循环逻辑,提高代码的复用。在之前的文章中和上面的代码中,都需全部数据获取到数组中,为何这里需要分批读取呢?当文件大的时候,这样可以方式内存溢出的问题。而且通常开发者的电脑配置(内存)会高于服务器的内存配置,在开发者的电脑没问题,不代表生产环境没有问题,还是推荐使用分批读取。

    Reference:

    ryelqy, Java实现添加压缩文件, https://www.cnblogs.com/ryelqy/p/10104167.html

  • 相关阅读:
    工作流系统中的语法标记系统
    通用附件管理功能改善
    规范数据库表字段大小写 小写字段名全部更改为大写
    Enterprise Solution 虚拟测试环境
    解析大型.NET ERP系统 查找与钻取
    Linux:FHS标准
    Linux:修改和删除已有变量
    分布式系统:高性能系统设计原则
    CAP:Alantany 谈 CAP
    Javascript:自己写模板引擎
  • 原文地址:https://www.cnblogs.com/ryelqy/p/14382467.html
Copyright © 2020-2023  润新知