一、断点续传
下载文件时,可以多线程分段下载,每个线程都负责下载一部分
断点续传测试地址:
http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe
服务器响应码
- 500: 服务器异常
- 404: 路径找不到
- 400: 参数类型错误
- 200: OK
- 206: 部分数据已OK
RandomAccessFile用来下载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VIqIXz7-1658449885317)(Img\image-20220721122552033.png)]
/**
* 直接下载
* http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe
*/
public class Demo01 {
public static void main(String[] args) {
String path = "http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe";
try {
//创建一个URL对象
URL url = new URL(path);
//打开连接,获取了url请求的连接对象conn
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//请求设置
conn.setConnectTimeout(5000);//请求的超时时间
conn.setReadTimeout(5000);//读取超时时间
conn.setRequestMethod("GET");//设置请求提交的方法Get Post
//获取响应码
int responseCode = conn.getResponseCode();//获取响应码
System.out.println("responseCode = " + responseCode);
//如果连接ok 200
if(responseCode==200){
//下载?
InputStream in = conn.getInputStream();//获取用于读取网络资源的输入流
//下载的流
String fileName = conn.getHeaderField("Content-Disposition");//获取响应的头部文件(包含由文件名)
fileName = fileName.split(";")[1];
fileName = fileName.substring(fileName.indexOf("\"")+1,fileName.lastIndexOf("\""));
//System.out.println(fileName);//成功获取文件名
File file = new File(fileName);
RandomAccessFile raf = new RandomAccessFile(file,"rwd");//可读、可写,有权限
//读一组,下载一组
byte[]bytes=new byte[1024];
int len = 0;
while((len=in.read(bytes))!=-1){
raf.write(bytes,0,len);
}
//关闭流释放资源
raf.close();
in.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
断点续传 核心代码代码
//设置请求头:断点续传的范围
conn.setRequestProperty("Range","bytes="+start+"-"+end);
//设置Range范围后,响应码为206(表示部分数据ok)
if(conn.getResponseCode()==206){
//statr-end这部分数据的下载代码
//可参考课堂案例的下载代码
//设置本次下载的部分数据从哪个位置开始
raf.seek(start);//【实现断点续传的核心方法】
}
伪代码提示:
一个程序入口类,开启下载
String path = "http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe";
try {
//创建一个URL对象
URL url = new URL(path);
//打开连接,获取了url请求的连接对象conn
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//请求设置
conn.setConnectTimeout(5000);//请求的超时时间
conn.setReadTimeout(5000);//读取超时时间
conn.setRequestMethod("GET");//设置请求提交的方法Get Post
//获取响应码
int responseCode = conn.getResponseCode();//获取响应码
System.out.println("responseCode = " + responseCode);
//如果连接ok 200
if(responseCode==200){
//设计分段下载(如分成3次下载)
//要下载的文件大小
int contentLength = conn.getContentLength();
//每个线程下载的大小
int size = contentLength/3;
//3.开启线程执行下载
for (int i = 0; i < 3; i++) {
//创建断点续传线程对象(下载一部分)
//设置下载哪一部分(start,end)
//线程对象.start();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
断点续传线程类
public class DownLoad extends Thread{
start;//起始位置
end;//结束位置
@Override
public void run() {
//创建一个URL对象
//打开连接,获取了url请求的连接对象conn
//请求设置
//请求的超时时间
//读取超时时间
//设置请求提交的方法Get Post
//设置线程本次断点续传文件范围
conn.setRequestProperty("Range","bytes="+start+"-"+end);//获取响应码
//获取响应码
if(响应码==206){//由于是部分数据 206就表示ok
//下载本段文件(参考课堂案例下载代码)
//...
//设置本次下载的部分数据从哪个位置开始RandomAccessFile的seek方法
//....
}
}
//get和set省略...
}
stProperty(“Range”,“bytes=”+start+“-”+end);//获取响应码
//获取响应码
if(响应码==206){//由于是部分数据 206就表示ok
//下载本段文件(参考课堂案例下载代码)
//...
//设置本次下载的部分数据从哪个位置开始RandomAccessFile的seek方法
//....
}
}
//get和set省略...
}