您的位置:首页 > 编程语言 > Java开发

Java_多线程_断点_下载

2016-06-29 18:41 375 查看
代码组成:

1.核心代码是通过GET请求获取数据;

2.用RandomAccessFile 创建 与获取的数据长度相同的 文件,该类可以指定数据写入文件的位置;

3.
conn.setRequestProperty("range", "bytes=" + startIndex + "-" + endIndex);


该方法可以设置 获取总数据中的 部分数据,注意:获取部分数据时,网络连接状态码是:206 (SC_PARTIAL_CONTENT)

//206 (SC_PARTIAL_CONTENT)是在服务器完成了一个包含Range头信息的局部请求时被发送的。

4.关键字 synchronized 解决多线程中同步问题

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

public class Down_BreakPoint {
//数据的长度
static int lenght;
//线程的个数
static int threadCount = 3;
//正在运行线程的格式
static int currentRunningThread = threadCount;
//数据的地址
static String path = "http://ossweb-img.qq.com/images/gameshop/dnf/1.jpg";

public static void main(String[] args) {
//数据的开始和结束位置
int startIndex,endIndex;

try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");

if(conn.getResponseCode() == 200) {
lenght = conn.getContentLength(); //获取数据长度
File file = new File(getFileName(path));   //创建文件
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.setLength(lenght);  //设置(空)文件大小
raf.close();

//设置每个线程所获得数据的开始和结束位置
in
a727
t blockSize = lenght/threadCount;
for(int threadId = 0; threadId < threadCount; threadId++ ) {
startIndex = threadId * blockSize;
endIndex = (threadId+1) * blockSize -1;
if(threadId == threadCount - 1){
endIndex = lenght -1;
}
System.out.println("start: " + startIndex + " ; end: " + endIndex);
//创建(下载)线程
DownloadFilePartThread thread = new DownloadFilePartThread(threadId, startIndex, endIndex);
thread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static class DownloadFilePartThread extends Thread {

private int startIndex;
private int threadId;
private int endIndex;
private File config;
private String index;   //记录线程当前写入数据开始位置

public DownloadFilePartThread(int threadId, int startIndex, int endIndex) {
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
index = startIndex + "";
config();   //初始化线程当前写入数据开始位置
}

private void config() {
config = new File(threadId + "");
if(config.exists() && config.length()>0){
BufferedReader br;
try {
br = new BufferedReader(new FileReader(config));
index = br.readLine();
startIndex = Integer.parseInt(index);
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

public void run() {
super.run();
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//设置接受属性--接收范围
conn.setRequestProperty("range", "bytes=" + startIndex + "-" + endIndex);
if(conn.getResponseCode() == 206) { //接收部分数据时,状态码为:206

InputStream is = conn.getInputStream();
File file = new File(getFileName(path));
RandomAccessFile raf = new RandomAccessFile(file, "rw");
//设置  开始写入的位置
raf.seek(startIndex);
int len = 0;
byte[] buffer = new byte[1024];
while((len = is.read(buffer))>0) {
raf.write(buffer, 0, len);
OutputStream os = new FileOutputStream(config);
index = Integer.parseInt(index) + len + "";
os.write(index.getBytes()); //写入配置文件当前写入数据的位置
os.close();
}
System.out.println("threadId: " + threadId + "Finish" );
is.close();
raf.close();
synchronized (Down_BreakPoint.class) { //解决线程安全问题

//删除配置文件
currentRunningThread--;
if(currentRunningThread == 0) {
File ff ;
for(int i = 0; i<threadCount ;i++){
ff = new File(i+"");
ff.delete();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}

}
}

public static String getFileName(String path) {
int index = path.lastIndexOf("/");
return path.substring(index + 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: