`
shuaigg.babysky
  • 浏览: 571425 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

使用java多线程机制实现下载

阅读更多
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
/**
* HTTP的多线程下载工具。
* 
* @author 赵学庆 www.java2000.net
*/
public class HTTPDownloader extends Thread {

  private String page;
  // 保存的路径
  private String savePath;
  // 线程数
  private int threadNumber = 2;
  // 来源地址
  private String referer;
 // 最小的块尺寸。如果文件尺寸除以线程数小于这个,则会减少线程数。
  private int MIN_BLOCK = 10 * 1024;
  public static void main(String[] args) throws Exception {
    HTTPDownloader d = new HTTPDownloader("http://sdn.kugou.com/link.aspx?id=3480&url=http%3a%2f%2fdownmini.kugoo.com%2fKuGou2010.exe", "d://a.exe", 10);
    d.down();
  }
  public void run() {
    try {
      down();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * 下载操作
   *  
   * @throws Exception
   */
  public void down() throws Exception {
    URL url = new URL(page); // 创建URL
    URLConnection con = url.openConnection(); // 建立连接
 int contentLen = con.getContentLength(); // 获得资源长度
    if (contentLen / MIN_BLOCK + 1 < threadNumber) {
      threadNumber = contentLen / MIN_BLOCK + 1; // 调整下载线程数
    }
    if (threadNumber > 10) {
      threadNumber = 10;
    }
    int begin = 0;
    int step = contentLen / threadNumber;
    int end = 0;
    for (int i = 0; i < threadNumber; i++) {
      end += step;
      if (end > contentLen) {
        end = contentLen;
      }
      new HTTPDownloaderThread(this, i, begin, end).start();
      begin = end;
    }
  }
  public HTTPDownloader() {
  }
  /**
   * 下载
   *  
   * @param page 被下载的页面
   * @param savePath 保存的路径
   */
  public HTTPDownloader(String page, String savePath) {
    this(page, savePath, 10);
  }
  /**
   * 下载
   *  
   * @param page 被下载的页面
   * @param savePath 保存的路径
   * @param threadNumber 线程数
   */
  public HTTPDownloader(String page, String savePath, int threadNumber) {
    this(page, page, savePath, 10);
  }
  /**
   * 下载
   *  
   * @param page 被下载的页面
   * @param savePath 保存的路径
   * @param threadNumber 线程数
   * @param referer 来源
   */
  public HTTPDownloader(String page, String referer, String savePath, int threadNumber) {
    this.page = page;
    this.savePath = savePath;
    this.threadNumber = threadNumber;
    this.referer = referer;
  }
  public String getPage() {
    return page;
  }
  public void setPage(String page) {
    this.page = page;
  }
  public String getSavePath() {
    return savePath;
  }
  public void setSavePath(String savePath) {
    this.savePath = savePath;
  }
  public int getThreadNumber() {
    return threadNumber;
  }
  public void setThreadNumber(int threadNumber) {
    this.threadNumber = threadNumber;
  }
  public String getReferer() {
    return referer;
  }
  public void setReferer(String referer) {
    this.referer = referer;
  }
}
/**
* 下载线程
*  
* @author 赵学庆 www.java2000.net
*/
class HTTPDownloaderThread extends Thread {
  HTTPDownloader manager;
  int startPos;
  int endPos;
  int id;
  int curPos;
  int BUFFER_SIZE = 4096;
  int readByte = 0;
  HTTPDownloaderThread(HTTPDownloader manager, int id, int startPos, int endPos) {
    this.id = id;
    this.manager = manager;
    this.startPos = startPos;
    this.endPos = endPos;
  }
  public void run() {
    // System.out.println("线程" + id + "启动");
    // 创建一个buff
    BufferedInputStream bis = null;
    RandomAccessFile fos = null;
    // 缓冲区大小
    byte[] buf = new byte[BUFFER_SIZE];
    URLConnection con = null;
    try {
      File file = new File(manager.getSavePath());
      // 创建RandomAccessFile
      fos = new RandomAccessFile(file, "rw");
      // 从startPos开始
      fos.seek(startPos);
      // 创建连接,这里会为每个线程都创建一个连接
      URL url = new URL(manager.getPage());
      con = url.openConnection();
      con.setAllowUserInteraction(true);
      curPos = startPos;
      // 设置获取资源数据的范围,从startPos到endPos
      con.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
      // 盗链解决
      con.setRequestProperty("referer", manager.getReferer() == null ? manager.getPage() : manager.getReferer());
      con.setRequestProperty("userAgent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
      // 下面一段向根据文件写入数据,curPos为当前写入的未知,这里会判断是否小于endPos,
      // 如果超过endPos就代表该线程已经执行完毕
      bis = new BufferedInputStream(con.getInputStream());
      while (curPos < endPos) {
        int len = bis.read(buf, 0, BUFFER_SIZE);
        if (len == -1) {
          break;
        }
        fos.write(buf, 0, len);
        curPos = curPos + len;
        if (curPos > endPos) {
          // 获取正确读取的字节数
          readByte += len - (curPos - endPos) + 1;
        } else {
          readByte += len;
        }
      }
      // System.out.println("线程" + id + "已经下载完毕:" + readByte);
      bis.close();
      fos.close();
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}

 

 

 

抄的别人的 , 自己写的有问题。学习一下。

分享到:
评论

相关推荐

    利用Java多线程机制实现带滚动字幕的时钟

    当用户在“命令”后的文本框中输入“start clock”后,“现在的时间是”后的文本框开始显示系统时钟;当用户输入“stop clock”后,时钟终止显示。 (2)当用户在“命令”后的文本框中输入“fast”后,能够加速滚动...

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...

    java多线程机制 详解

    Java的多线程机制是Java语言的一大特性,它允许程序同时执行多个任务,提升程序响应速度,优化资源利用率。在Java中,线程是程序执行的最小单位,一个进程可以包含多个线程,每个线程都有自己独立的生命周期,包括...

    java多线程实现大批量数据导入源码

    本项目以"java多线程实现大批量数据导入源码"为题,旨在通过多线程策略将大量数据切分,并进行并行处理,以提高数据处理速度。 首先,我们需要理解Java中的线程机制。Java通过`Thread`类来创建和管理线程。每个线程...

    Java多线程实现异步调用实例

    总之,Java多线程和异步调用是构建高效、响应迅速的应用程序的关键技术。通过合理利用这些工具和机制,开发者可以编写出能够充分利用多核处理器优势的代码,从而提高软件性能。在实际应用中,理解并熟练掌握这些概念...

    Java多线程下载器

    Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...

    Java多线程知识点总结

    总之,掌握Java多线程的生命周期、创建、启动、同步以及线程池的使用是编写高效、稳定并发程序的基础。理解这些知识点对于解决并发编程中的问题,比如资源竞争、死锁、线程安全性等问题,至关重要。在实际开发中,...

    java多线程进度条

    本主题将深入探讨如何在Java多线程环境下实现进度条功能。 首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,...

    java多线程模拟队列实现排队叫号

    总的来说,通过Java多线程和队列数据结构,我们可以有效地模拟排队叫号系统。这种模拟有助于理解和实践并发编程,同时也为我们解决实际问题提供了思路。在这个过程中,我们学习了线程同步、队列操作以及如何在Java中...

    Java多线程机制(示例)

    ### Java多线程机制详解与示例 ...通过上述介绍和示例,我们可以看到Java多线程机制的强大功能以及其实现的灵活性。合理地利用多线程机制可以显著提高程序的性能和响应能力,对于开发高效的应用程序至关重要。

    java多线程简单下载器

    【Java多线程简单下载器】是一个初学者的编程作业,虽然代码可能较为混乱,但其核心功能已经实现,即通过多线程技术进行文件的下载。在Java中,多线程是并发处理的重要手段,它允许多个任务在同一时间执行,从而提高...

    Java多线程下载

    为了解决这个问题,Java多线程下载利用了操作系统并发处理的能力,将一个大文件分割成多个小部分,每个部分由一个独立的线程负责下载,从而实现断点续传,提高下载速度。 首先,理解Java多线程的基础概念至关重要。...

    java实现多线程下载

    2. **Java多线程实现**: - 实现方式一:继承`Thread`类。创建一个新的类,继承自`Thread`,重写`run()`方法,然后创建该类的实例并调用`start()`方法启动线程。 - 实现方式二:实现`Runnable`接口。创建一个类,...

    java多线程详解(比较详细的阐述了多线程机制)

    本文将深入探讨Java多线程机制,包括线程的创建、同步、通信以及常见设计模式。 首先,Java中创建线程主要有两种方式:通过实现Runnable接口和继承Thread类。实现Runnable接口更灵活,因为Java是单继承的,而通过...

    java多线程下载器

    Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个小部分,然后创建多个线程同时下载这些部分,以提高下载速度。这种技术在处理大文件或者网络带宽有限的情况下尤其有用,...

    基于Java多线程机制的探析

    ### 基于Java多线程机制的探析 #### 摘要 本文深入探讨了Java多线程机制的基本原理及其应用场景。首先简要分析了Java多线程的概念及其实现方法,随后详细介绍了多线程在多用户远程协同工作系统中的应用,特别是...

    java多线程经典案例

    通过分析并实践`threadTest`案例,我们可以深入理解Java多线程的原理和使用技巧,为编写高效并发程序打下坚实基础。同时,也要注意多线程编程中的死锁、活锁和饥饿等问题,合理设计线程间的交互,避免出现不可预期的...

    java多线程下载图片

    在这个场景中,"java多线程下载图片"意味着我们将探讨如何使用Java来实现一个能够异步下载多个图片的系统。 首先,我们需要理解Java中的线程是如何创建和运行的。Java提供了两种创建线程的方式:继承Thread类和实现...

    java多线程应用实现示例

    总结,这个"java多线程应用实现示例"通过小球运动的模拟,深入浅出地展示了Java多线程的运用,包括线程创建、同步、通信和线程池管理等关键概念。学习这个示例有助于理解和掌握Java多线程编程,为实际项目开发中的...

    Java的多线程机制分析与应用.pdf

    Java多线程机制是Java语言中一个重要的特征,可以通过对Java中的多线程创建机制和使用方法进行探讨,分析多线程中的同步必要性和实现方式,并给出多线程的实际应用示例。 Java多线程机制可以将程序任务划分为若干...

Global site tag (gtag.js) - Google Analytics