SpringBoot實現文件下載的幾種方式


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();

————————————————
版權聲明:本文為CSDN博主「user2025」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/user2025/article/details/107300831


免責聲明!

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



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