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

多线程断点下载文件

2014-10-03 17:48 323 查看
             hello 大家好!习惯了记录点点滴滴。  十一在家太无聊了,又想到最近工作中碰到了一个需求,如何提高玩家下载速度.... 于是看到了jdk api 突然发现还有一个

RandomAccessFile 类     瞬间发觉自己对api 还是有点生疏啊 学习之路还很长很长 哈哈...  好了 先讲下实现思路吧!

  什么是下载? 我想大家这个应该多知道吧!不解释了 。 主要讲下 什么是多线程断点续传? 通俗点讲就是  把需要下载的文件比喻成 一桶水,下载的过程就是把水释放掉... 然而我们之前电脑cpu 是单核的 单核cpu下载可以说释放水只是通过一个洞释放的..  而现在cpu 基本都是i5 ,i7 了 哈哈 所以我们就希望充分多核提高下载速度 也就是说 往水桶里面多刺破几个洞.......
  

多线程短点续传 实现 原理:
      1:  读取网上文件总的大小, 之后在本地生成一个临时文件夹和需要下载文件的大小同等
      2:  把网上需要下载的文件 与 启动下载线程数 相除 得到每个线程需要下载大小任务
      3: 把每个线程下载的数据 拼接成一个文件  下载完成
看代码吧!

如下代码是  线程续传 实现:
/**
* 多线程 续传 实现
* @author jade
*
*/
class ThreadDowFile implements Runnable {

private String threadName;
private int startIndex;
private int endIndex;
private String url;
private String fileName;

ThreadDowFile(String threadName, int startIndex, int endIndex, String url,
String fileName) {
this.threadName = threadName;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.url = url;
this.fileName = fileName;

}

public void writ() {

try {

URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("GET");

conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
+ endIndex);
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();

System.out.println("code=" + code);
System.out.println(Thread.currentThread().getName()
+ "  单次线程下载 :文件总的大小 空间是  ::  " + conn.getContentLength());
InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile(fileName, "rwd");
raf.seek(startIndex);// 定位文件
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("线程" + threadName + "下载完毕");

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

@Override
public void run() {

writ();
}

}


测试下载类:
 
/**
* 学习演示多线程下载方案 多点断续 多线程下载
* @author jade
*
*/
public class ThreadReadFile {

public static void main(String[] args) {

RandomAccessFile raf = null;
String urlpath = "http://download.efun.com/sgyx/sgyx.apk";    // 网上 待下载资源
String fileName = "/Volumes/ssd/Users/jade/Downloads/jade.apk";    //需要下载到本地 位置
int threadTotal = 3; // 需要启用多少线程下载文件
int thradStream = 0; // 每个线程需要下载的流
int maxFileLegh = 0;
int statyCode = -1;

try {
URL u = new URL(urlpath);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("GET");
maxFileLegh = conn.getContentLength();
conn.setConnectTimeout(5000);
System.out.println(maxFileLegh);
statyCode = conn.getResponseCode();

System.out.println(statyCode);
if (statyCode == 200) {  // 参考 api code 定义含义
thradStream = maxFileLegh / threadTotal;
raf = new RandomAccessFile(fileName, "rwd");
raf.setLength(maxFileLegh);
raf.close();
System.out.println("文件总的大小 空间是  ::  " + maxFileLegh);
System.out.println("每个线程 任务下载流分配 :  " + thradStream);

for (int threadId = 1; threadId <= threadTotal; ++threadId) {
// 第一个线程下载的开始位置
int startIndex = (threadId - 1) * thradStream;
int endIndex = (startIndex + thradStream) - 1;
if (threadId == threadTotal) {
// 最后一个线程下载的长度稍微长一点
endIndex = maxFileLegh;
}

System.out.println("线程:" + threadId + "下载:--" + startIndex
+ "-->" + endIndex);
new Thread(new ThreadDowFile(" 线程编号 : " + threadId,
startIndex, endIndex, urlpath, fileName)).start();
}
} else {

System.out.println("request error");

}

} catch (Exception e) {

e.printStackTrace();
}
}

}


执行结果:

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