最近开始学习java,尝试实现浏览器文件下载,使用IDEA15构建了Springboot maven工程。根据网上的资料做了比较多的尝试,也遇到了
许多问题,在此记录总结一下。由于是本地局域网的测试,所以代码中的文件的源目录都是直接写死的本地目录。
方式一:
@RequestMapping("mydownload")
public ResponseEntity<Object> download(HttpServletResponse response) throws IOException {
String path = "D:\\111.ts";
File file = new File(path);
long size = file.length();
//为了解决中文名称乱码问题 这里是设置文件下载后的名称
String fileName = new String("000.ts".getBytes("UTF-8"), "iso-8859-1");
response.reset();
response.setHeader("Accept-Ranges", "bytes");
//设置文件下载是以附件的形式下载
response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
response.addHeader("Content-Length", String.valueOf(size));
ServletOutputStream sos = response.getOutputStream();
FileInputStream in = new FileInputStream(file);
BufferedOutputStream outputStream = new BufferedOutputStream(sos);
byte[] b = new byte[1024];
int i = 0;
while ((i = in.read(b)) > 0) {
outputStream.write(b, 0, i);
}
outputStream.flush();
sos.close();
outputStream.close();
in.close();
return new ResponseEntity<Object>(HttpStatus.OK);
}
方式二:
//文件下载相关代码 与上面的方法类似
@RequestMapping("/download")
public String downloadFile(HttpServletRequest request, HttpServletResponse response) {
String fileName = "111.mov";
if (fileName != null) {
//当前是从该工程的WEB-INF//File//下获取文件(该目录可以在下面一行代码配置)
String realPath = request.getServletContext().getRealPath(
"WEB-INF/File/");
File file = new File(realPath, fileName);
if (file.exists()) {
// 设置强制下载不打开
response.setContentType("application/force-download");
// 设置文件名
response.addHeader("Content-Disposition",
"attachment;fileName=" + fileName);
byte[] buffer = new byte[1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
System.out.println("success");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
方式三(在方式一的基础上加了下载进度和下载速度的简单实现):
@Component
@Scope("prototype")
@RequestMapping("/downloadFile")
public class DownloadActionc {
@RequestMapping("downloadFiletest")
public ResponseEntity<Object> download(HttpServletResponse response) throws IOException {
String path = "D:\\abc.ts";
File file = new File(path);
String fileName = new String("test.ts".getBytes("UTF-8"), "iso-8859-1");
long fileTotalsize = file.length();
System.out.println("fileTotalsize = " + fileTotalsize);
response.reset();
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
response.addHeader("Content-Length", String.valueOf(fileTotalsize));
ServletOutputStream sos = response.getOutputStream();
FileInputStream in = new FileInputStream(file);
BufferedOutputStream outputStream = new BufferedOutputStream(sos);
byte[] b = new byte[1024 * 2];//每次传输2K
long filecomplateSize = 0L;
double rateSpeed = 0;//速度
long rateProcess = 0L;//进度
int readSize = 0;
int i = 0;
int nbytes = 0;
long startTime = System.nanoTime();
//这里是下载进度和速度的简单实现 没有使用单独的线程进行速度计算
while ((readSize = in.read(b)) > 0) {
if (i % 20 == 0) {
startTime = System.nanoTime();
}
filecomplateSize = filecomplateSize + readSize;
outputStream.write(b, 0, readSize);
nbytes = readSize + nbytes;
if (i % 20 == 19) {
rateProcess = filecomplateSize / fileTotalsize;
//时间差 System.nanoTime()的返回值精确度是毫微秒
double currentTime = (System.nanoTime() - startTime);
//将速度转化成比较通用的MB/S
rateSpeed = ((nbytes / currentTime) * 1000 * 1000 * 1000) / 1024 / 1024;
String strrateSpeed = String.format("%.2f", rateSpeed);
rateSpeed = Double.valueOf(strrateSpeed);
System.out.println(rateSpeed);
System.out.println(rateSpeed);
nbytes = 0;
}
i++;
}
outputStream.flush();
outputStream.close();
sos.close();
in.close();
return new ResponseEntity<Object>(HttpStatus.OK);
}
在做下载的测试学习中了解到,浏览器的下载的目标路径程序中是不能修改的,这是浏览器自己的安全机制,所以浏览器的文件下载
是下载到浏览器中设置的默认的下载路径中。
本人是Java开发的小白,若有问题请各位大神及时指正指教。
项目下载地址(仅作为参考或者测试):http://download.youkuaiyun.com/detail/coding13/9801171