首页
登录 | 注册

使用Java实现http多线程下载

本文转载自JavaEye,点此查看全文
关键字: java http 下载 多线程 下载工具我想没有几个人不会用的吧,前段时间比较无聊,花了点时间用java写了个简单的http多线程下载程序,纯粹是无聊才写的,只实现了几个简单的 功能,而且也没写界面,今天正好也是一个无聊日,就拿来写篇文章,班门弄斧一下,觉得好给个掌声,不好也不要喷,谢谢!

我实现的这个http下载工具功能很简单,就是一个多线程以及一个断点恢复,当然下载是必不可少的。那么大概先整理一下要做的事情:
1、 连接资源服务器,获取资源信息,创建文件
2、 切分资源,多线程下载
3、 断点恢复功能
4、 下载速率统

   1. String urlStr = “http://www.sourcelink.com/download/xxx”; //资源地址,随便写的
   2. URL url = new URL(urlStr); //创建URL

   3. URLConnection con = url.openConnection(); //建立连接

   4. contentLen = con.getContentLength(); //获得资源长度

   5. File file = new File(filename); //根据filename创建一个下载文件,也会是我们最终下载所得的文件

很简单吧,没错就是这么简单,第一步做完了,那么接下来要做第二步,切分资源,实现多线程。在上一步我们已经获得了资源的长度contentLen,那么 如何根据这个对资源进行切分呢?假如我们要运行十个线程,那么我们就先把contentLen处以10,获得每块的大小,然后在分别创建十个线程,每个线 程负责其中一块的写入,这就需要利用到RandomAccessFile这个类了,这个类提供了对文件的随机访问,可以指定向文件中的某一个位置进行写入 操作,大致代码如下:

   1. long subLen = contentLen / threadQut; //获取每块的大小

   2.
   3. //创建十个线程,并启动线程

   4. for (int i = 0; i < threadQut; i++) {
   5. DLThread thread = new DLThread(this, i + 1, subLen * i, subLen * (i + 1) - 1); //创建线程

   6. dlThreads[i] = thread;
   7. QSEngine.pool.execute(dlThreads[i]); //把线程交给线程池进行管理

   8. }

在这里使用到了DLThread这个类,我们先来看看这个类的构造方法的定义:

public DLThread(DLTask dlTask, int id, long startPos, long endPos)

第一个参数为一个DLTask,这个类就代表一个下载任务,里面主要保存这一个下载任务的信息,包括下载资源名,本地文件名等等的信息。第二个参 数就是一个标示线程的id,如果有10个线程,那么这个id就是从1到10,第三个参数startPos代表该线程从文件的哪个地方开始写入,最后一个参 数endPos代表写到哪里就结束。

我们再来看看,一个线程启动后,具体如何去下载,请看run方法:

   1. public void run() {
   2. System.out.println("线程" + id + "启动......");
   3. BufferedInputStream bis = null; //创建一个buff

   4. RandomAccessFile fos = null;
   5. byte[] buf = new byte[BUFFER_SIZE]; //缓冲区大小

   6. URLConnection con = null;
   7. try {
   8. con = url.openConnection(); //创建连接,这里会为每个线程都创建一个连接

   9. con.setAllowUserInteraction(true);
  10. if (isNewThread) {
  11. con.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);//设置获取资源数据的范围,从startPos到endPos

  12. fos = new RandomAccessFile(file, "rw"); //创建RandomAccessFile

  13. fos.seek(startPos); //从startPos开始

  14. } else {
  15. con.setRequestProperty("Range", "bytes=" + curPos + "-" + endPos);
  16. fos = new RandomAccessFile(dlTask.getFile(), "rw");
  17. fos.seek(curPos);
  18. }
  19. //下面一段向根据文件写入数据,curPos为当前写入的未知,这里会判断是否小于endPos,

  20. //如果超过endPos就代表该线程已经执行完毕

  21. bis = new BufferedInputStream(con.getInputStream());
  22. while (curPos < endPos) {
  23. int len = bis.read(buf, 0, BUFFER_SIZE);
  24. if (len == -1) {
  25. break;
  26. }
  27. fos.write(buf, 0, len);
  28. curPos = curPos + len;
  29. if (curPos > endPos) {
  30. readByte += len - (curPos - endPos) + 1; //获取正确读取的字节数

  31. } else {
  32. readByte += len;
  33. }
  34. }
  35. System.out.println("线程" + id + "已经下载完毕。");
  36. this.finished = true;
  37. bis.close();
  38. fos.close();
  39. } catch (IOException ex) {
  40. ex.printStackTrace();
  41. throw new RuntimeException(ex);
  42. }
  43. }


相关文章

  • 联通iphone 3GS 双模双待,WIFI上网,双摄蓝牙,JAVA炒股,4G内存
                     http://www.131.hk/goods.php?id=988                        订购电话:4006-333-242 全球首发台版原装iPhone 3GS首款WIFI双模联 ...
  • "作为一名C++程序员,我们早已掌握了面向对象程序设计的基本概念,而且Java的语法无疑是非常熟悉的.事实上,Java本来就是从C++衍生出来的." 然而,C++和Java之间仍存在一些显著的差异.可以这样说,这些差异代 ...
  • 情景: 这两天公司要与招商银行的网银进行对接,系统中已经安装了支持java预言的1.6最新版本的jdk,但是现在需要的让系统中php程序支持java,才能完成,下面对此情况进行简单说明: 使用php-java-bridge让PHP5支持ja ...
  • JSP 简介 什么是Java Server Pages(Java服务器页面)? JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以结束. JSP是一种Javas ...
  • 1,下载安装Java的JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html  (JDK中,包含JRE) 如果是64位的系统,推荐安装64位的java. ...
  • 安装centos 7的时候出现An Unknown Error Has Occurred
    https://www.cnblogs.com/umask/p/7446580.html 生成安装 生成安装 USB 介质,常见的使用工具:UltraISO PowerISO USBWriter Rufus(UltraISO 写入新的驱动器 ...

2020 unjeep.com webmaster#unjeep.com
12 q. 0.014 s.
京ICP备10005923号