欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實(shí)現(xiàn)文件下載功能的方式分享

 更新時(shí)間:2023年03月23日 14:56:11   作者:向一路北  
這篇文章主要為大家詳細(xì)介紹了SpringBoot這哪個(gè)實(shí)現(xiàn)文件下載功能的幾種方式,文中的實(shí)現(xiàn)方法簡介易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

1. 將文件以流的形式一次性讀取到內(nèi)存,通過響應(yīng)輸出流輸出到前端

/**
 * @param path     想要下載的文件的路徑
 * @param response
 * @功能描述 下載文件:
 */
@RequestMapping("/download")
public void download(String path, HttpServletResponse response) {
    try {
        // path是指想要下載的文件的路徑
        File file = new File(path);
        log.info(file.getPath());
        // 獲取文件名
        String filename = file.getName();
        // 獲取文件后綴名
        String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        log.info("文件后綴名:" + ext);

        // 將文件寫入輸入流
        FileInputStream fileInputStream = new FileInputStream(file);
        InputStream fis = new BufferedInputStream(fileInputStream);
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();

        // 清空response
        response.reset();
        // 設(shè)置response的Header
        response.setCharacterEncoding("UTF-8");
        //Content-Disposition的作用:告知瀏覽器以何種方式顯示響應(yīng)返回的文件,用瀏覽器打開還是以附件的形式下載到本地保存
        //attachment表示以附件方式下載   inline表示在線打開   "Content-Disposition: inline; filename=文件名.mp3"
        // filename表示文件的默認(rèn)名稱,因?yàn)榫W(wǎng)絡(luò)傳輸只支持URL編碼的相關(guān)支付,因此需要將文件名URL編碼后進(jìn)行傳輸,前端收到后需要反編碼才能獲取到真正的名稱
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        // 告知瀏覽器文件的大小
        response.addHeader("Content-Length", "" + file.length());
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        outputStream.write(buffer);
        outputStream.flush();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

2. 將輸入流中的數(shù)據(jù)循環(huán)寫入到響應(yīng)輸出流中,而不是一次性讀取到內(nèi)存,通過響應(yīng)輸出流輸出到前端

/**
* @param path     指想要下載的文件的路徑
* @param response
* @功能描述 下載文件:將輸入流中的數(shù)據(jù)循環(huán)寫入到響應(yīng)輸出流中,而不是一次性讀取到內(nèi)存
*/
@RequestMapping("/downloadLocal")
public void downloadLocal(String path, HttpServletResponse response) throws IOException {
   // 讀到流中
   InputStream inputStream = new FileInputStream(path);// 文件的存放路徑
   response.reset();
   response.setContentType("application/octet-stream");
   String filename = new File(path).getName();
   response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
   ServletOutputStream outputStream = response.getOutputStream();
   byte[] b = new byte[1024];
   int len;
   //從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)字節(jié)數(shù)組中,讀到末尾返回-1
   while ((len = inputStream.read(b)) > 0) {
       outputStream.write(b, 0, len);
   }
   inputStream.close();
}

3. 下載網(wǎng)絡(luò)文件到本地

/**
* @param path       下載后的文件路徑和名稱
* @param netAddress 文件所在網(wǎng)絡(luò)地址
* @功能描述 網(wǎng)絡(luò)文件下載到服務(wù)器本地
*/
@RequestMapping("/netDownloadLocal")
public void downloadNet(String netAddress, String path) throws IOException {
	  URL url = new URL(netAddress);
	  URLConnection conn = url.openConnection();
	  InputStream inputStream = conn.getInputStream();
	  FileOutputStream fileOutputStream = new FileOutputStream(path);
	
	  int bytesum = 0;
	  int byteread;
	  byte[] buffer = new byte[1024];
	  while ((byteread = inputStream.read(buffer)) != -1) {
	      bytesum += byteread;
	      System.out.println(bytesum);
	      fileOutputStream.write(buffer, 0, byteread);
	  }
	  fileOutputStream.close();
}

4. 網(wǎng)絡(luò)文件獲取到服務(wù)器后,經(jīng)服務(wù)器處理后響應(yīng)給前端

/**
 * @param netAddress
 * @param filename
 * @param isOnLine
 * @param response
 * @功能描述 網(wǎng)絡(luò)文件獲取到服務(wù)器后,經(jīng)服務(wù)器處理后響應(yīng)給前端
 */
@RequestMapping("/netDownLoadNet")
public void netDownLoadNet(String netAddress, String filename, boolean isOnLine, HttpServletResponse response) throws Exception {

    URL url = new URL(netAddress);
    URLConnection conn = url.openConnection();
    InputStream inputStream = conn.getInputStream();

    response.reset();
    response.setContentType(conn.getContentType());
    if (isOnLine) {
        // 在線打開方式 文件名應(yīng)該編碼成UTF-8
        response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, "UTF-8"));
    } else {
        //純下載方式 文件名應(yīng)該編碼成UTF-8
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
    }

    byte[] buffer = new byte[1024];
    int len;
    OutputStream outputStream = response.getOutputStream();
    while ((len = inputStream.read(buffer)) > 0) {
        outputStream.write(buffer, 0, len);
    }
    inputStream.close();
}

5. 常見異常和問題

(1)響應(yīng)對象無需通過return返回

原因:  響應(yīng)對象是可以不用作為方法返回值返回的,其在方法執(zhí)行時(shí)已經(jīng)開始輸出,且其無法與@RestController配合,以JSON格式返回給前端

解決辦法: 刪除return語句

(2)返回前端的文件名必須進(jìn)行URL編碼

原因: 網(wǎng)絡(luò)傳輸只能傳輸特定的幾十個(gè)字符,需要將漢字、特殊字符等經(jīng)過Base64等編碼來轉(zhuǎn)化為特定字符,從而進(jìn)行傳輸,而不會亂碼

URLEncoder.encode(fileName, "UTF-8")

(3)IO流有待學(xué)習(xí)

1:read() : 從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié),返回0到255范圍內(nèi)的int字節(jié)值。如果因?yàn)橐呀?jīng)到達(dá)流末尾而沒有可用的字節(jié),則返回-1。在輸入數(shù)據(jù)可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。

2:read(byte[] b) : 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)數(shù)組 b 中。以整數(shù)形式返回實(shí)際讀取的字節(jié)數(shù)。在輸入數(shù)據(jù)可用、檢測到文件末尾或者拋出異常前,此方法一直阻塞。如果 b 的長度為 0,則不讀取任何字節(jié)并返回 0;否則,嘗試讀取至少一個(gè)字節(jié)。如果因?yàn)榱魑挥谖募┪捕鴽]有可用的字節(jié),則返回值 -1

以上就是SpringBoot實(shí)現(xiàn)文件下載功能的方式分享的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot文件下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入了解java中的逃逸分析

    深入了解java中的逃逸分析

    這篇文章主要介紹了深入了解java中的逃逸分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java實(shí)例化的幾種方法總結(jié)

    Java實(shí)例化的幾種方法總結(jié)

    這篇文章主要介紹了Java實(shí)例化的幾種方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Java本地高性能緩存的幾種常見實(shí)現(xiàn)方式

    Java本地高性能緩存的幾種常見實(shí)現(xiàn)方式

    在Java中緩存是一種常用的性能優(yōu)化技術(shù),用于在應(yīng)用程序中加速訪問和查詢數(shù)據(jù)的速度,下面這篇文章主要給大家介紹了關(guān)于Java本地高性能緩存的幾種常見實(shí)現(xiàn)方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • java反射深入剖析(推薦)

    java反射深入剖析(推薦)

    下面小編就為大家?guī)硪黄猨ava反射深入剖析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-07-07
  • JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常

    JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常

    這篇文章主要介紹了JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 詳解MyBatis日志如何做到兼容所有常用的日志框架

    詳解MyBatis日志如何做到兼容所有常用的日志框架

    這篇文章主要介紹了詳解MyBatis日志如何做到兼容所有常用的日志框架,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • idea啟動(dòng)多個(gè)服務(wù)不顯示Services或者RunDashboard窗口的處理方法

    idea啟動(dòng)多個(gè)服務(wù)不顯示Services或者RunDashboard窗口的處理方法

    這篇文章主要介紹了idea啟動(dòng)多個(gè)服務(wù)不顯示Services或者RunDashboard窗口,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 基于java實(shí)現(xiàn)畫圖板功能

    基于java實(shí)現(xiàn)畫圖板功能

    這篇文章主要為大家詳細(xì)介紹了基于java實(shí)現(xiàn)畫圖板功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • jar包和war包區(qū)別解析

    jar包和war包區(qū)別解析

    jar是java普通項(xiàng)目打包,通常是開發(fā)時(shí)要引用通用類,打成jar包便于存放管理,war是java web項(xiàng)目打包,web網(wǎng)站完成后,打成war包部署到服務(wù)器,目的是為了節(jié)省資源,提供效率,這篇文章主要介紹了jar包和war包區(qū)別及理解,需要的朋友可以參考下
    2023-07-07
  • idea遠(yuǎn)程調(diào)試spark的步驟講解

    idea遠(yuǎn)程調(diào)試spark的步驟講解

    今天小編就為大家分享一篇關(guān)于idea遠(yuǎn)程調(diào)試spark的步驟講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03

最新評論