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

java中多线程下载

2015-07-03 18:01 543 查看
package com.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MutileThreadDown {
private static int blockCount=3;
private static int blockSize;
public static void main(String[] args) throws Exception{
String path="http://localhost:8080/Web025Server/media/bootstrap.avi";

URL url=new URL(path);

HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10000);
conn.setReadTimeout(5000);
int responseCode=conn.getResponseCode();
if(responseCode==200){
int size=conn.getContentLength();
System.out.println("服务器端的长度"+size);
blockSize=size/blockCount;

//创建一个跟服务器端大小相同的空白文件
File file=new File("aa.avi");
RandomAccessFile raf=new RandomAccessFile(file,"rw");
raf.setLength(size);//设置文件的的大小
//2.开启若干个子线程,分别下载资源
for(int i=1;i<=blockCount;i++){
int startIndex=(i-1)*blockSize+0;
int endIndex=i*blockSize-1;
if(i==blockCount){
endIndex=size-1;
}
new DownLoadThread(startIndex, endIndex, i, path).start();;
System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex);
}
}
conn.disconnect();
}

//定义一个线程的内部类
private static class DownLoadThread extends Thread{
private int startIndex;
private int endIndex;
private int threadi;
private String path;
public DownLoadThread(int startIndex, int endIndex, int threadi,
String path) {
super();
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadi = threadi;
this.path = path;
}
@Override
public void run() {

try {
String path="http://localhost:8080/Web025Server/media/bootstrap.avi";

URL url=new URL(path);

HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
conn.setConnectTimeout(10000);
conn.setReadTimeout(5000);
int responseCode=conn.getResponseCode();
System.out.println("服务器的响应码"+responseCode);

//创建一个跟服务器端大小相同的空白文件
File file=new File("aa.avi");
RandomAccessFile raf=new RandomAccessFile(file,"rw");
InputStream in=conn.getInputStream();
raf.seek(startIndex);//从哪个位置开始写文件
int len=-1;
byte[] bytes=new byte[1024];
while((len=in.read(bytes))!=-1){
raf.write(bytes, 0, len);
}
in.close();
raf.close();

} catch (Exception e) {
e.printStackTrace();
}
}
}

}
下面我再贴一下更新后的代码吧,这个可以实现短点下载,关闭程序重新开启后可以继续下载
package com.download;

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

public class MutileThreadDown {
private static int blockCount=3;//定义需要开启线程的个数
private static int blockSize;

private static int runningThreadCount;//正在运行的线程的数量
public static void main(String[] args) throws Exception{

String path="http://localhost:8080/Web025Server/media/bootstrap.avi";
URL url=new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10000);
conn.setReadTimeout(5000);

int responseCode=conn.getResponseCode();
if(responseCode==200){
int size=conn.getContentLength();
System.out.println("服务器端的长度"+size);//服务器端需要下载文件的大小
blockSize=size/blockCount;

//创建一个跟服务器端大小相同的空白文件
File file=new File("aa.avi");
RandomAccessFile raf=new RandomAccessFile(file,"rw");
raf.setLength(size);//设置文件的的大小
//2.开启若干个子线程,分别下载资源
runningThreadCount=blockCount;//刚开始设定正在运行的线程数是线程的总数
for(int i=1;i<=blockCount;i++){
int startIndex=(i-1)*blockSize+0;
int endIndex=i*blockSize-1;
if(i==blockCount){
endIndex=size-1;//最后一个线程需要下载剩下的
}
new DownLoadThread(startIndex, endIndex, i, path).start();;
System.out.println("开启线程"+i+"开始的位置"+startIndex+"结束的位置是"+endIndex);
}
}
conn.disconnect();
}

//定义一个线程的内部类
private static class DownLoadThread extends Thread{
private int startIndex;
private int endIndex;
private int threadi;
private String path;
public DownLoadThread(int startIndex, int endIndex, int threadi,
String path) {
super();
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadi = threadi;
this.path = path;
}
@Override
public void run() {

try {
//获取当前下载总文件的大小
int total=0;
File filepos=new File(threadi+".txt");//建立一个txt文件记录下载的信息
String path="http://localhost:8080/Web025Server/media/bootstrap.avi";

URL url=new URL(path);

HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//接着从上一次位置下载
if(filepos.exists()&&filepos.length()>0){//判断以前是否下载过
FileInputStream fis=new FileInputStream(filepos);
BufferedReader br=new BufferedReader(new InputStreamReader(fis));
String lasttotalstr=br.readLine();//获取当前线程上一次下载的总大小
int lasttotal=Integer.valueOf(lasttotalstr);
System.out.println("上一次下载的总大小"+lasttotal);
startIndex+=lasttotal;
total+=lasttotal;
fis.close();//很重要
}

conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
conn.setConnectTimeout(10000);
conn.setReadTimeout(5000);
int responseCode=conn.getResponseCode();
System.out.println("服务器的响应码"+responseCode);

//创建一个跟服务器端大小相同的空白文件
File file=new File("aa.avi");
RandomAccessFile raf=new RandomAccessFile(file,"rw");
InputStream in=conn.getInputStream();
raf.seek(startIndex);//从哪个位置开始写文件
int len=-1;
byte[] bytes=new byte[1024*1024];

while((len=in.read(bytes))!=-1){
RandomAccessFile rf=new RandomAccessFile(filepos, "rwd");
raf.write(bytes, 0, len);
total+=len;
rf.write(String.valueOf(total).getBytes());
rf.close();
}
in.close();
raf.close();

} catch (Exception e) {
e.printStackTrace();
} finally{
synchronized (this) {
runningThreadCount--;
if(runningThreadCount==0){
System.out.println("所有线程下载完毕,可以删除txt记录文件了");//可能会出现线程安全问题
for(int i=1;i<=blockCount;i++){
File f=new File(i+".txt");
boolean b=f.delete();
System.out.println(b);
}
}
}

}
}
}

}


本文出自 “Java大白的战地” 博客,请务必保留此出处http://8023java.blog.51cto.com/10117207/1670663
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: