• 批量打包成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

  • 相关阅读:
    3. 无重复字符的最长子串
    字节跳动 最小栈
    排序
    线程的优先级
    线程的操作方法
    线程的生命周期
    实现线程的方式:Thread类重写run();Runnable类重写run();Callable类重写call();实现线程的方式
    Java thread run() start() 是干什么的以及区别
    Java thread 多线程
    助教工作学期总结
  • 原文地址:https://www.cnblogs.com/ryelqy/p/14382467.html
Copyright © 2020-2023  润新知