SpringBoot 文件下載、分片下載

普通下載功能的實現(xiàn)

    FileInputStream inputStream = null;
    ServletOutputStream os = null;
    try {
        inputStream = new FileInputStream(file);

        //設(shè)置響應(yīng)狀態(tài)200
        response.setStatus(HttpServletResponse.SC_OK);
        //設(shè)置內(nèi)容類型
        response.setContentType(getContentType(fileId));
        //添加響應(yīng)頭 設(shè)置內(nèi)容長度
        response.addHeader("Content-Length", String.valueOf(file.length()));
        //添加響應(yīng)頭 設(shè)置允許瀏覽器可嘗試恢復(fù)中斷的下載
        response.addHeader("Accept-Ranges", "bytes");
        response.addHeader("Cache-control", "private");
        //添加響應(yīng)頭 設(shè)置瀏覽器另存為對話框的默認(rèn)文件名
        response.addHeader("Content-Disposition", "filename=" + file.getName());
        response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");

        os = response.getOutputStream();

        byte[] buf = new byte[1024];
        int len;
        while ((len = inputStream.read(buf)) != -1) {
            os.write(buf, 0, len);
            os.flush();
        }
    } catch (Exception e) {
        //操作文件失敗時返回響應(yīng)狀態(tài) 500
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    } finally {
        //結(jié)束后釋放資源
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

支持分片下載功能的實現(xiàn)

  • 這里是因為測試中ios safari 瀏覽器無法正常打開播放視頻文件,通過抓取分析瀏覽器訪問靜態(tài)資源視頻過程實現(xiàn)的代碼
    //獲取請求頭
    String range = request.getHeader("range");
    String referer = request.getHeader("referer");
    //處理range 計算請求的哪部分?jǐn)?shù)據(jù)
    String[] split = range.split("bytes=|-");
    long begin = 0;
    if (split.length >= 2) {
        begin = Long.valueOf(split[1]);
    }
    long end = file.length() - 1;
    if (split.length >= 3) {
        end = Long.valueOf(split[2]);
    }
    long len = (end - begin) + 1;
    //如果請求的文件長度超過文件實際長度 返回錯誤狀態(tài)
    if (end > file.length()) {
        //返回狀態(tài) 500
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    }

    FileInputStream inputStream = null;
    ServletOutputStream os = null;
    try {
        //創(chuàng)建文件流
        inputStream = new FileInputStream(file);
        //將指針移到請求片段的開始位置
        inputStream.skip(begin);
        //設(shè)置響應(yīng)狀態(tài) 206 部分內(nèi)容
        response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
        //設(shè)置內(nèi)容類型
        response.setContentType(getContentType(fileId));
        //添加響應(yīng)頭 設(shè)置片段開始位置 結(jié)束位置 文件總長度
        response.addHeader("Content-Range", "bytes " + begin + "-" + end + "/" + file.length());
        //添加響應(yīng)頭 設(shè)置響應(yīng)片段的長度
        response.addHeader("Content-Length", String.valueOf(len));
        //添加響應(yīng)頭 設(shè)置允許瀏覽器可嘗試恢復(fù)中斷的下載
        response.addHeader("Accept-Ranges", "bytes");
        response.addHeader("Cache-control", "private");
        //添加響應(yīng)頭 設(shè)置瀏覽器另存為對話框的默認(rèn)文件名
        response.addHeader("Content-Disposition", "filename=" + file.getName());
        response.addHeader("Last-Modified", new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss Z", Locale.ENGLISH).format(file.lastModified()) + " GMT");

        os = response.getOutputStream();
        //從文件流中讀指定長度的片段輸出
        byte[] buf = new byte[1024];
        while (len > 0) {
            inputStream.read(buf);
            long l = len > 1024 ? 1024 : len;
            os.write(buf, 0, (int) l);
            os.flush();
            len -= l;
        }
    } catch (Exception e) {
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
    } finally {
        //釋放資源
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 昨天在例會上,做了一件錯的事情,再次看到自己在某些事情上思維的混亂,看到自己的急躁,看到自己有限的包容心,看到自己...
    韓彥芳閱讀 195評論 0 2
  • 進(jìn)入了大學(xué),我們肯定會遇到很多事情,課程壓力,學(xué)業(yè)壓力,社團(tuán),考證,培訓(xùn)…… 好多好多事情,有時候你會...
    想當(dāng)個咸魚閱讀 255評論 -1 2
  • hello,我叫馮后蓮,大家都叫我阿蓮!今天我給大家講講我的經(jīng)歷!我是重慶永川人,土生土長的農(nóng)村妹兒!我沒有...
    馮后蓮閱讀 899評論 6 16
  • 休息十點(diǎn)多才起來吃早餐,吃完早餐看了一會書十二點(diǎn)多又去吃午飯,吃完飯看了一會書感覺看不進(jìn)去了,看了一會電視說等下去...
    o蛋撻o閱讀 249評論 0 5

友情鏈接更多精彩內(nèi)容