您的位置:首页 > 其它

实现多线程下载同一个文件

2016-03-18 19:01 597 查看
原理:


示例代码:

public class LoadFile {

private static int threadCount = 3;// 下载的线程数量

public static void main(String[] args) {

// 1、与服务器建立连接,获得文件的大小,在本地创建一个与需下载文件同等大小的临时文件
String path = "http://localhost/safe.exe";
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);

int code = conn.getResponseCode();
if(200 == code) {
// 获得文件的长度
int length = conn.getContentLength();
System.out.println("文件总长度为:"+length);
// 在本地创建一个可以随机读取的与源文件同等大小的临时文件
RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
// 指定文件的长度
raf.setLength(length);// 设置文件长度
raf.close();

// 2、实现多线程下载资源
int blockSize = length / threadCount ;// 每个线程平均需要下载文件的大小
for(int threadId = 1; threadId <= threadCount; threadId++) {
// 每个线程下载文件的初始位置和结束位置
int startIndex = (threadId-1) * blockSize;
int endIndex = threadId * blockSize - 1;
// 下载的最后一块的情况
if(threadCount == threadId) {
endIndex = length - 1;// 如果不减1的话,就超出了文件的范围
}
System.out.println("线程 "+threadId+"下载位置为:"+startIndex+"--->"+endIndex);
// 启动下载线程
new DownloadThread(path, startIndex, endIndex, threadId).start();
}

} else {
System.out.println("服务器出现错误");
}

} catch (Exception e) {
System.out.println("连接服务器URL出现错误");
e.printStackTrace();
}

}

}

public class DownloadThread extends Thread {

private String path;// 服务器路径
private int startIndex;// 块文件开始位置
private int endIndex;// 快文件结束位置
private int threadId;// 线程编号

public DownloadThread() {

}

public DownloadThread(String path, int startIndex, int endIndex, int threadId) {
this.path = path;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
}

@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
// 提交请求可以从指定位置读取文件
conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
+ endIndex);
int code = conn.getResponseCode();
// 请求全部文件成功返回200, 请求部分文件成功返回206
if (206 == code) {
RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
// 随机文件从哪里读
raf.seek(startIndex);// 定位文件

InputStream is = conn.getInputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
raf.write(buffer, 0, len);
}

is.close();
raf.close();
System.out.println("线程" + threadId + "下载完毕!!!!");
} else {
System.out.println("线程"+threadId+"请求的部分资源失败");
}

} catch (Exception e) {
System.out.println("下载线程的URL连接异常");
e.printStackTrace();
}
}

}
// 别下载太大的文件,可能等待时间很长
/*Output:
文件总长度为:11556608
线程 1下载位置为:0--->3852201
线程 2下载位置为:3852202--->7704403
线程 3下载位置为:7704404--->11556607
线程2下载完毕!!!!
线程1下载完毕!!!!
线程3下载完毕!!!!
*/



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: