前言:
程序下载文件时,有时会因为各种各样的原因下载中断,对于小文件来说影响不大,可以快速重新下载,但是下载大文件时,就会耗费很长时间,所以断点续传功能对于大文件很有必要。
文件下载的断点续传:
1、先下载临时文件,用于记录已下载大小:
2、http请求时设置Range参数
3、下载此次请求的数据;
直接上代码:
代码语言:javascript复制 1 package com.test.service;
2
3 import java.io.File;
4 import java.io.InputStream;
5 import java.io.RandomAccessFile;
6 import java.net.HttpURLConnection;
7 import java.net.URL;
8 import java.text.NumberFormat;
9
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Value;
13 import org.springframework.stereotype.Component;
14
15 /**
16 * <p>
17 * 文件下载,可以支持断点续传
18 * 暂未使用
19 * </p>
20 * @author
21 * @version 1.0
22 * */
23 @Component
24 public class DownloadOnly {
25
26 private static final Logger logger = LoggerFactory.getLogger(DownloadOnly.class);
27
28 @Value("${onair.download.ddxc:true}")
29 boolean ddxc = true;
30
31 int startIndex = 0;
32
33 long downloadSize = 0;
34
35 boolean downloadFinish = false;
36
37 int totleSize = 0;
38
39 public boolean download(String url,String file_path,int downloadTimeout){
40
41 //起一个线程 检测下载进度
42 new Thread(new Runnable() {
43
44 @Override
45 public void run() {
46 try {
47 NumberFormat nt = NumberFormat.getPercentInstance();
48 //设置百分数精确度3即保留三位小数
49 nt.setMinimumFractionDigits(1);
50 while(!downloadFinish){
51 Thread.sleep(30000);
52 logger.debug("已下载大小{},进度{}",getDownloadSize(),nt.format(getDownloadSize()* 1.0 /totleSize));
53 }
54 } catch (InterruptedException e) {
55 e.printStackTrace();
56 }
57
58 }
59 }).start();
60
61 logger.info("下载文件:源路径{},目标路径:{}",url,file_path);
62 RandomAccessFile raf = null;
63 InputStream in = null;
64
65 try {
66 URL file_url = new URL(url);
67 HttpURLConnection conn = (HttpURLConnection)file_url.openConnection();
68 conn.setConnectTimeout(downloadTimeout);
69 conn.setRequestMethod("GET");
70 File tmpFile = new File(file_path "_tmp");
71 if(ddxc){
72 if(tmpFile.exists() && tmpFile.isFile()){
73 downloadSize = tmpFile.length();
74 startIndex = (int)downloadSize;
75 }
76 conn.setRequestProperty("Range", "bytes=" startIndex "-");
77 }else{
78 if(tmpFile.exists() && tmpFile.isFile())
79 tmpFile.delete();
80 }
81 int status = conn.getResponseCode();
82 totleSize = (int)downloadSize conn.getContentLength();
83 logger.info("文件总大小{},下载请求获得的返回状态码:{},需要下载的大小{}",totleSize,status,totleSize-downloadSize);
84 if(status== 200 || status == 206 ){
85 raf = new RandomAccessFile(tmpFile, "rwd");
86 raf.seek(startIndex);
87 in = conn.getInputStream();
88 byte[] buffer = new byte[1024];
89 int size = 0;
90 while((size=in.read(buffer)) !=-1 ){
91 raf.write(buffer, 0, size);
92 downloadSize = size;
93 }
94 raf.close();
95 in.close();
96 File dest = new File(file_path);
97 return tmpFile.renameTo(dest);
98 }
99 } catch (Throwable e) {
100 logger.error("文件下载失败:{}",e.getMessage(),e);
101 }finally {
102 downloadFinish = true; //下载完成或中断
103 }
104 return false;
105 }
106
107 public long getDownloadSize() {
108 return downloadSize;
109 }
110
111 public static void main(String[] args) {
112 DownloadOnly downloadOnly = new DownloadOnly();
113 }
114
115 }