前言
因为传统IO文件传输速率低,所以选择了NIO进行文件的下载操作。NIO还有一个好处就是其中零拷贝可以实现减少内存中数据的重复,减少CPU操作的效果。所以相对于传统IO,NIO有着效率高点的优势。
NIO实现文件下载工具类
NIO零拷贝下载的工具类,可以直接使用。
package com.zhao.annotationaop.utils;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
/**NIO文件下载工具类
* @author zhao
*/
public class NioDownloadUtils {
/**
* @description:
* @param file: 要下在文件
* @return: void
*/
public static void downloadDoc(File file,HttpServletResponse response) throws IOException {
OutputStream outputStream = response.getOutputStream();
String contentType = Files.probeContentType(Paths.get(file.getAbsolutePath()));
//设置响应头
response.setHeader("Content-Type", contentType);
response.setHeader("Content-Disposition", "attachment;filename="+ new String(file.getName().getBytes("utf-8"),"ISO8859-1"));
response.setContentLength((int) file.length());
//获取文件输入流
FileInputStream fileInputStream = new FileInputStream(file);
//获取输出流通道
WritableByteChannel writableByteChannel = Channels.newChannel(outputStream);
FileChannel fileChannel = fileInputStream.getChannel();
//采用零拷贝的方式实现文件的下载
fileChannel.transferTo(0,fileChannel.size(),writableByteChannel);
//关闭对应的资源
fileChannel.close();
outputStream.flush();
writableByteChannel.close();
}
public static void downloadDoc(String path,HttpServletResponse response) throws IOException {
File file = new File(path);
if (!file.exists()){
throw new RuntimeException("文件不存在");
}
downloadDoc(file,response);
}
}
测试
首先编写一个Controller进行测试:
DocDownloadTestController
package com.zhao.annotationaop.controller;
import com.zhao.annotationaop.utils.NioDownloadUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class DocDownloadTestController {
@RequestMapping("/download.do")
public void download(HttpServletRequest request, HttpServletResponse response){
String url = request.getParameter("url");
if (StringUtils.isEmpty(url)){
throw new RuntimeException("文件文件为空");
}
try {
NioDownloadUtils.downloadDoc(url,response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:这里不要使用@RestController
注解,要使用@Controller
注解
测试一下
- 启动项目
- 在浏览器中输入网址加上要下载的文件的路径:
http://localhost:8083/download.do?url=C:%5CUsers%5C32596%5CDesktop%5Cnacos%E6%9E%B6%E6%9E%84%E5%92%8C%E5%8E%9F%E7%90%86.pdf
注意这里的参数是经过URL编码之后的。因为在浏览器请求的的时候,地址栏中的地址会进行URL编码之后才会去请求。所以这里需要先编码之后在请求。
版权声明:本文为weixin_46897073原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。