使用Java实现多线程下载断点续传功能案例

来源:互联网 发布:永宏编程手册 编辑:程序博客网 时间:2024/05/22 12:23

   Java实现多线程下载断点续传功能案例   2017年7月25日00:11:06



package com.itheima.download;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class MulitDownload {
//设置线程数量
static int thradCount =3;
//设置线程数量读取
static int finishedThread =0;
//1.设置获取下载地址Path
static String path ="http://192.168.108.2:8080/WPS.exe";
    public static void main(String[] args) {


//2.设置URL侦听
    try {
URL url = new URL(path);
//3.设置建立网络连接
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
//4.设置请求方式
conn.setRequestMethod("GET");
//设置响应时长和返回时长
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
//5.建立网络连接
conn.connect();
//6.判断响应码是否为200
if(conn.getResponseCode() ==200){
//7.获取下载文件大小
int length = conn.getContentLength();
//设置保存位置
File file = new File(getFileName(path));
//8.设置缓存
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
//设置临时文件大小
raf.setLength(length);
raf.close();
//9.设置每个线程读取多少
int size = length / thradCount;
for( int i =0; i<thradCount ;i++){
int startIndex = i * size;
int endIndex = (i+1) * size -1;
if(i == thradCount-1){
endIndex = length -1;
}
System.out.println("线程数"+i+"开始区间"+startIndex+"--"+endIndex);
new DownloadThrad(startIndex, endIndex, i).start();
 
}
 

}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


    public static String getFileName(String path){
    int index = path.lastIndexOf("/");
    return path.substring(index +1);
    }
}
class DownloadThrad extends Thread{
int startIndex;
int endIndex;
int threadId;

public DownloadThrad(int startIndex, int endIndex, int threadId) {
super();
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
URL url;
try {
//设置断点续传ID
   File progressFile = new File(threadId+".txt");
   if(progressFile.exists()){
    FileInputStream fis = new FileInputStream(progressFile);
    BufferedReader bf = new BufferedReader(new InputStreamReader(fis));
       startIndex +=Integer.valueOf(bf.readLine());
   }
   System.out.println("线程"+threadId+"开始节点"+startIndex+"后续"+endIndex);
url = new URL(MulitDownload.path);
//3.设置建立网络连接
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
//4.设置请求方式
conn.setRequestMethod("GET");
//设置响应时长和返回时长
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
//拿到节点
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
//判断当前节点是否为206
if(conn.getResponseCode() ==206){
//获取输入流
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len =0;
int total =0;
File file = new File(MulitDownload.getFileName(MulitDownload.path));
RandomAccessFile raf = new RandomAccessFile(file, "rwd");
//指定从哪个节点开始 
raf.seek(startIndex);
while((len = is.read(b))!=-1){
raf.write(b, 0, len);
total +=len;
System.out.println("当前线程"+threadId+"下载"+total);
 


//设置缓存读取
RandomAccessFile progressRaf = new RandomAccessFile(progressFile, "rwd");
//设置写入文本信息
progressRaf.write((total+"").getBytes());
progressRaf.close();
 
}
raf.close();
   //设置读取线程 数量
MulitDownload.finishedThread++;
//同步语句
synchronized (MulitDownload.path) {
if(MulitDownload.finishedThread == MulitDownload.thradCount){
for(int i=0;i<MulitDownload.thradCount;i++){
File f = new File( i +".txt");
f.delete();
  System.out.println("打印当前"+i);
}
//设置判断为0
MulitDownload.finishedThread =0;
}

}
 
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

}