Java多线程下载的基础类,类似于迅雷,QQ旋风等下载器一样的原理。
package com.shenzhen.mutiledownload2014;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 测试多线程下载的样例
*
* @author mayubao
*
*/
public class TestDownload {
public static final String path = "http://192.168.1.120:8080/a.zip";
public static final void main(String[] args) throws Exception {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打开一个链接
// 设置一个请求的相关信息
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
// Gecko/20100101 Firefox/29.0
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
int code = conn.getResponseCode();
if (code == 200) {// 请求过去且回复内容正常的话
int len = conn.getContentLength();
RandomAccessFile file = new RandomAccessFile("D:/temp/test/"
+ getFileName(path), "rwd");
// 1.创建一个本地文件跟服务器的大小一致
file.setLength(len);
// 2.根据服务器中要下载的文件大小划分要多少个线程
int threadnum = 3;
int blocksize = len / threadnum;
/**
* 多线程下载 线程1 0 ~ blocksize 线程2 blocksize*1 ~ blocksize*2 线程3
* blocksize*2 ~ len
*/
for (int i = 0; i < threadnum; i++) {
int startposition = i * blocksize;
int endposition = (i + 1) * blocksize;
if (i == (threadnum - 1)) {// 最后一个线程的话,那么就另endposition=len
endposition = len;
}
// 分别执行每一个线程
new DownloadTask(i, path, startposition, endposition).start();
}
}
// conn.setRequestProperty(key, value);
}
public static String getFileName(String path) {
int start = path.lastIndexOf("/");
return path.substring(start, path.length());
}
}
/**
* 下载的线程类
*
* @author mayubao
*
*/
class DownloadTask extends Thread {
private int id;
private String path;
private int startposition;
private int endposition;
public DownloadTask(int id, String path, int startposition, int endposition) {
this.id = id;
this.path = path;
this.startposition = startposition;
this.endposition = endposition;
}
@Override
public void run() { // 每一个线程体要执行的内容
URL url;
try {
url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置一个请求的相关信息
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
// User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
// Gecko/20100101 Firefox/29.0
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
InputStream is = conn.getInputStream();
RandomAccessFile file = new RandomAccessFile(getFileName(path),
"rwd");
file.seek(startposition);
// 将反馈回来的输入流写到RandomAccessFile里面去
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {// 输入流没到尽头
file.write(buffer, 0, len);
}
file.close();
System.out.println("第" + id + "个线程已经下载完成了");
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
public static String getFileName(String path) {
int start = path.lastIndexOf("/");
return path.substring(start, path.length());
}
}