<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1. 將檔案以流的形式一次性讀取到記憶體,通過響應輸出流輸出到前端
/** * @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(); // 設定response的Header response.setCharacterEncoding("UTF-8"); //Content-Disposition的作用:告知瀏覽器以何種方式顯示響應返回的檔案,用瀏覽器開啟還是以附件的形式下載到本地儲存 //attachment表示以附件方式下載 inline表示線上開啟 "Content-Disposition: inline; filename=檔名.mp3" // filename表示檔案的預設名稱,因為網路傳輸只支援URL編碼的相關支付,因此需要將檔名URL編碼後進行傳輸,前端收到後需要反編碼才能獲取到真正的名稱 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. 將輸入流中的資料迴圈寫入到響應輸出流中,而不是一次性讀取到記憶體,通過響應輸出流輸出到前端
/** * @param path 指想要下載的檔案的路徑 * @param response * @功能描述 下載檔案:將輸入流中的資料迴圈寫入到響應輸出流中,而不是一次性讀取到記憶體 */ @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; //從輸入流中讀取一定數量的位元組,並將其儲存在緩衝區位元組陣列中,讀到末尾返回-1 while ((len = inputStream.read(b)) > 0) { outputStream.write(b, 0, len); } inputStream.close(); }
3. 下載網路檔案到本地
/** * @param path 下載後的檔案路徑和名稱 * @param netAddress 檔案所在網路地址 * @功能描述 網路檔案下載到伺服器本地 */ @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. 網路檔案獲取到伺服器後,經伺服器處理後響應給前端
/** * @param netAddress * @param filename * @param isOnLine * @param response * @功能描述 網路檔案獲取到伺服器後,經伺服器處理後響應給前端 */ @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) { // 線上開啟方式 檔名應該編碼成UTF-8 response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, "UTF-8")); } else { //純下載方式 檔名應該編碼成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)響應物件無需通過return返回
原因: 響應物件是可以不用作為方法返回值返回的,其在方法執行時已經開始輸出,且其無法與@RestController配合,以JSON格式返回給前端
解決辦法: 刪除return語句
(2)返回前端的檔名必須進行URL編碼
原因: 網路傳輸只能傳輸特定的幾十個字元,需要將漢字、特殊字元等經過Base64等編碼來轉化為特定字元,從而進行傳輸,而不會亂碼
URLEncoder.encode(fileName, "UTF-8")
(3)IO流有待學習
1:read() : 從輸入流中讀取資料的下一個位元組,返回0到255範圍內的int位元組值。如果因為已經到達流末尾而沒有可用的位元組,則返回-1。在輸入資料可用、檢測到流末尾或者丟擲異常前,此方法一直阻塞。
2:read(byte[] b) : 從輸入流中讀取一定數量的位元組,並將其儲存在緩衝區陣列 b 中。以整數形式返回實際讀取的位元組數。在輸入資料可用、檢測到檔案末尾或者丟擲異常前,此方法一直阻塞。如果 b 的長度為 0,則不讀取任何位元組並返回 0;否則,嘗試讀取至少一個位元組。如果因為流位於檔案末尾而沒有可用的位元組,則返回值 -1
以上就是SpringBoot實現檔案下載功能的方式分享的詳細內容,更多關於SpringBoot檔案下載的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45