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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM