package cn.hp.demo01; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; /** * 断点续传 * 分段下载 */ public class Demo01 { public static void main(String[] args) { int threadCount = 3;//分为3段,创建3个线程对象来下载 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/threadCount; /* 0 1 2 3 4 5 6 7 8 9 10个数据 10/3=3 每个下载3个 线程1:0 1 2 start=i*size end=(i+1)*size-1 线程2:3 4 5 start=i*size end=(i+1)*size-1 线程3:6 7 8 9 start=i*size end=9(最后一个线程最好直接到长度) */ //3.开启线程执行下载 for (int i = 0; i < threadCount; i++) { //创建断点续传线程对象(下载一部分) DownLoadThread dt = new DownLoadThread(); //设置下载哪一部分(start,end) dt.setPath(path); dt.setStart(i*size); if(i==2){//如果是最后一段数据,就到文件结尾 dt.setEnd(contentLength); }else{ dt.setEnd((i+1)*size); } //线程对象.start(); dt.start(); } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /** * 子线程,下载指定某一段数据 */ class DownLoadThread extends Thread{ private String path;//要下载的地址 private int start;//起始位置 private int end;//结束位置 @Override public void run() { //创建一个URL对象 try { URL url = new URL(path); //打开连接,获取了url请求的连接对象conn HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //请求设置 //请求的超时时间 //读取超时时间 //设置请求提交的方法Get Post //设置线程本次断点续传文件范围 conn.setRequestProperty("Range","bytes="+start+"-"+end);//获取响应码 //获取响应码 int responseCode = conn.getResponseCode(); if(responseCode==206){//由于是部分数据 206就表示ok //下载本段文件(参考课堂案例下载代码) 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");//可读、可写,有权限 //设置本次下载的部分数据从哪个位置开始RandomAccessFile的seek方法 raf.seek(start);//写入文件时,直接从文件对应的位置开始写 //读一组,下载一组 byte[]bytes=new byte[1024]; int len = 0; while((len=in.read(bytes))!=-1){ raf.write(bytes,0,len); } //关闭流释放资源 raf.close(); in.close(); //线程下载完毕 System.out.println(this.getName()+":负责的"+start+"-"+end+" 下载完毕.."); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //get和set省略... public String getPath() { return path; } public void setPath(String path) { this.path = path; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getEnd() { return end; } public void setEnd(int end) { this.end = end; } }
断点续传分段下载
最新推荐文章于 2024-07-30 14:55:06 发布