1需求场景
当我们下载文件时由于某种原因中断了连接,导致文件只下载了一部分到本地。
但是我们又不想重新开始下载,现在我们需要继续接着上次中断处继续下载文件。
2编程实现
这样的需求很难实现吗?其实不难。
git地址完整代码路径:
断点续传Demo完整代码路径
1)创造断点场景
首先为了重现暂停下载的场景,可以用这个方法:
/**
* 下载网络资源的一部分
* @param startPosition 起始下载位置
* @param endPosition 终止下载位置
* @param urlAddress 网络资源的url
*/
public static void download(long startPosition, long endPosition,String urlAddress){
try {
URL url = new URL(urlAddress);// 获得网络资源的URL
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();// 获得连接对象
connection.setRequestProperty("User-Agent", "NetFox");// 设置请求属性
String rangeProperty = "bytes=" + startPosition + "-";// 定义请求范围属性
if (endPosition > 0) {
rangeProperty += endPosition;// 调整请求范围属性
}
connection.setRequestProperty("RANGE", rangeProperty);// 设置请求范围属性
connection.connect();// 连接网络资源
InputStream in = connection.getInputStream();// 获得输入流对象
String file = url.getFile();// 获得文件对象
String name = file.substring(file.lastIndexOf('/') + 1);// 获得文件名
FileOutputStream out = new FileOutputStream(name, true);// 创建输出流对象,保存下载的资源
byte[] buff = new byte[2048];// 创建字节数组
int len = 0;// 定义存储读取内容长度的变量
len = in.read(buff);// 读取内容
while (len != -1) {
out.write(buff, 0, len);// 写入磁盘
len = in.read(buff);// 读取内容
}
out.close();// 关闭流
in.close();// 关闭流
connection.disconnect();// 断开连接
} catch (Exception e) {
e.printStackTrace();
}
}
测试:
public static void main(String[] args) throws IOException {
String urlAddress="https://cn.bing.com/sa/simg/Flag_Feedback.png";
CoreCode.download(0,CoreCode.getResourceLength(urlAddress)-100,urlAddress);
}
运行之,结果如下:
打开看看:(因为这是不完整的,所以打不开是正常的)
2)实现断点续传
然后就是我们的核心代码,实现断点续传的方法。
此程序的逻辑起始很简单:
首先判断该文件是否是暂停下载的文件
如果是则获取其大小和完整资源的大小得到下载区间
然后接着这个下载区间进行下载即可。
/**
* 支持自动断点续传的下载方法
* @param urlStr 网络资源的url
*/
public static void downloadResource(String urlStr){
long startPosition=0;
long endPosition=0;
try {
URL url = new URL(urlStr);// 获得网络资源的URL
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();// 获得连接对象
String file = url.getFile();// 获得文件对象
String name = file.substring(file.lastIndexOf('/') + 1);// 获得文件名
File fileOb=new File(name);
//判断是否是暂停下载的文件
if(fileOb.exists()){
startPosition=fileOb.length();
endPosition=getResourceLength(urlStr);
}
connection.setRequestProperty("User-Agent", "NetFox");// 设置请求属性
String rangeProperty = "bytes=" + startPosition + "-";// 定义请求范围属性
if (endPosition > 0) {
rangeProperty += endPosition;// 调整请求范围属性
}
connection.setRequestProperty("RANGE", rangeProperty);// 设置请求范围属性
connection.connect();// 连接网络资源
InputStream in = connection.getInputStream();// 获得输入流对象
FileOutputStream out = new FileOutputStream(name, true);// 创建输出流对象,保存下载的资源
byte[] buff = new byte[2048];// 创建字节数组
int len = 0;// 定义存储读取内容长度的变量
len = in.read(buff);// 读取内容
while (len != -1) {
out.write(buff, 0, len);// 写入磁盘
len = in.read(buff);// 读取内容
}
out.close();// 关闭流
in.close();// 关闭流
connection.disconnect();// 断开连接
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给定url地址获取资源的大小(以字节为单位)
* @param urlStr
* @return
* @throws IOException
*/
public static long getResourceLength(String urlStr) throws IOException {
URL url=new URL(urlStr);
URLConnection urlConnection=url.openConnection();
urlConnection.connect();
return urlConnection.getContentLength();
}
测试:
public static void main(String[] args) throws IOException {
String url="https://cn.bing.com/sa/simg/Flag_Feedback.png";
CoreCode.downloadResource(url);
}
断点续传后,可以看到,完整的文件被下载了下来,顺利打开:
欢迎大家提出自己的看法。