javaWeb不生成臨時檔案實現壓縮檔案下載

wyzdeng發表於2020-11-17

   談起壓縮檔案的下載,我們可能會想到先生成壓縮檔案到伺服器,然後再從伺服器讀取壓縮檔案流,然後實現下載功能。但往往我們有時候不需要伺服器上儲存生成的臨時物理檔案(因為這樣會很浪費資源嗎),那麼我們該如何實現呢?下面阿燈就給大家分享一個簡單的實現demo思路吧。

        1、讀取或生成需要放進壓縮包中的檔案內容。

        2、使用ZipOutputStream在記憶體中生成壓縮檔案流。

        3、將生成的壓縮流放進response的輸出流中,最終實現下載。

示例程式碼如下:

@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping("zip")
    public void downLoadZip(HttpServletResponse response) throws Exception {
        //需要讀取檔案的完整路徑
        String filePath ="E:\\test\\download.docx";
        //建立ByteArrayOutputStream 儲存壓縮流,後期用於讀出壓縮檔案流內容
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        /**
         * 建立ZipOutputStream 用於生成壓縮檔案流
         * 這裡為什麼用ByteArrayOutputStream物件構造ZipOutputStream
         * 翻看ZipOutputStream建構函式的原始碼,你會發現
         * ZipOutputStream(OutputStream out) out引數的註釋為
         * out引數的註釋為 the actual output stream
         * 也就是說out物件是壓縮檔案的實際輸出流
         */
        ZipOutputStream zos = new ZipOutputStream(bos);
        //建立壓縮檔案內容例項,這裡我就建立一個,
        // 如果大家需要建立多個可多次putNextEntry
        zos.putNextEntry(new ZipEntry("download.docx"));
        //讀取檔案內容,並將檔案內容放到壓縮流中
        FileInputStream fis = new FileInputStream(filePath);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            System.out.println(new String(buffer));
            zos.write(buffer, 0, len);
        }
        //關閉流
        fis.close();
        zos.close(); //切記要先關閉流,不然後續無法獲取壓縮流內容
        //獲取壓縮位元組流,到這裡就明白為什麼使用ByteArrayOutputStream構造ZipOutputStream了吧
        byte[] zipBytes = bos.toByteArray();
        //下面就是下載的那一套了
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/x-msdownload");
        String filename = new String("壓縮檔案下載.zip".getBytes(),"ISO8859-1");
        response.addHeader("Content-Disposition","attachment;filename=" + filename);
        /**
         * 由於需要向響應體中放入位元組流 所以要放入response.getOutputStream();
         * 千萬不要習慣性的使用response.getWriter()哦
         */
        ServletOutputStream servletOutputStream = response.getOutputStream();
        servletOutputStream.write(zipBytes);
        servletOutputStream.close();
    }
}

 

                                        上述程式碼示例註釋已經很清楚了,相信看完程式碼的你,思路已經很明確了吧!

                                        當然,上述僅僅是寫了個簡單的demo,具體實現和優化還需要大家自行完成,

                                          有了清晰的思路,還擔心搞不定嗎?,

                                       個人感覺在程式中,有了清晰的思路,實現起來,一切都風雨無阻了。

                                        朋友們,擼起袖子,幹吧!

                                                 掃描或長按下方二維碼關注公眾號

                                                       持久關注阿燈的動態

                                         

 

相關文章