目录
方式二:基于NIO实现文件的下载 - Channle组件及其API来实现!
内容:本质上仍然是基于Java的IO(特别是File IO)流实现文件的读与写(只不过这个时候的写是往浏览器”写")
方式一:基于传统的IO
Controller层-得到附件对象,拼接完整文件的路径,将文件转化为输入流写入response对象之中
//下载文件
@RequestMapping(value = "file/download/{id}", method=RequestMethod.GET)
@ResponseBody
public String addItemAndUpload(@PathVariable Integer id, HttpServletResponse response){
if(id == null || id <= 0){
return null;
}
try{
Appendix appendix = itemService.getAppendixUrl(id);
String fileUrl = env.getProperty("file.upload.location.root.url") + appendix.getFileUrl();
System.out.println("appendixName:" + appendix.getName());
FileInputStream is = new FileInputStream(fileUrl);
commonService.downloadFile(response, is, appendix.getName());
return appendix.getName();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
CommonService层-循环读写
public void downloadFile(HttpServletResponse response, InputStream is, final String fileName) throws Exception{
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try{
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(response.getOutputStream());
//设置相应类型和响应头
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("utf-8"), "iso-8859-1"));
//TODO:其实就是一个不断读、写的过程
byte[] buffer = new byte[10240];
int len = bis.read(buffer);
while(len != -1){
bos.write(buffer, 0, len);
len = bis.read(buffer);
}
bos.flush();
}finally {
if(bis != null){
bis.close();
}
if(bos != null){
bos.close();
}
if(is != null){
is.close();
}
}
}
方式二:基于NIO实现文件的下载 - Channle组件及其API来实现!
本质:仍然是读取待下载的文件,转化为输入流,通过Channel复制到输出流,最终写回浏览器的响应对象中(只不过中间的整个过程是非阻塞式的)
public void downloadFileV2(HttpServletResponse response, FileInputStream is, final String fileName) throws Exception{
//设置相应类型和响应头
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("utf-8"), "iso-8859-1"));
int bufferSize=10240;
byte[] byteArr = new byte[bufferSize];
FileChannel fileChannel = is.getChannel();
ByteBuffer buffer = ByteBuffer.allocateDirect(61440);
try{
int nRead;
int nGet;
while((nRead=fileChannel.read(buffer)) != -1){
if(nRead == 0){
continue;
}
buffer.position(0);
buffer.limit(nRead);
while (buffer.hasRemaining()){
nGet = Math.min(buffer.remaining(), bufferSize);
//TODO: 从磁盘中读I - Input
buffer.get(byteArr, 0, nGet);
//TODO: 往浏览器响应流写O - Output
response.getOutputStream().write(byteArr);
}
buffer.clear();
}
}finally {
buffer.clear();
fileChannel.close();
is.close();
}
}