Java多线程分段下载

一直以来,想写一个多线程下载的程序。苦于没得时间,前短时间连续阴雨天,打开电脑百无聊奈。
就把这个程序写了出来。现在发出来,供大家参考。

首先,做分段下载,那么我们得分清楚每一块的数据格式。下图是多线程分段下载的示例图。
 

1:分段文件块的类
  1. package com.eibit.javalearning;

  2. import java.io.Serializable;

  3. /**
  4. * Created by Administrator on 2016/4/15.
  5. */
  6. public class BlockBean implements Serializable{
  7.         private static final long serialVersionUID = 1L;
  8.         //最大的下载尝试次数
  9.         public static final int MAX_TRY_COUNT = 10;
  10.         /**
  11.          * 每次尝试下载的次数
  12.          */
  13.         public int tryCount = 1;
  14.     /**
  15.      * 偏移量
  16.      */
  17.     public long offset = 0;
  18.     /**
  19.      * 分配给本线程的下载字节数
  20.      */
  21.     public long length = 0;
  22.     /**
  23.      * 已下载的字节数
  24.      */
  25.     public long downloadedLength = 0;
  26.     /**
  27.      * block的编号
  28.      */
  29.     public  int i;

  30.     public BlockBean(int i, long offset, long length) {
  31.         this.i = i;
  32.         this.offset = offset;
  33.         this.length = length;
  34.         this.downloadedLength = 0;
  35.     }
  36. }
复制代码

2:下载进度监听接口
  1. package com.eibit.javalearning;

  2. public interface DownListener {

  3.         /**
  4.          * 开始下载
  5.          */
  6.         void onStartDownLoad();
  7.         
  8.         /**
  9.          * 下载进度改变
  10.          * @param completeRate 下载进度
  11.          * @param speed 下载速度 KB/S
  12.          */
  13.         void onCompleteRateChanged(int completeRate);
  14.         
  15.         /**
  16.          * 下载完成
  17.          * @param fileName 存储的文件名
  18.          */
  19.         void onDownloadCompleted(String fileName);

  20.         /**
  21.          * 开启多线程下载
  22.          * @param numberThread 线程数量
  23.          */
  24.         void onStartMultiDownLoad(int numberThread);

  25.         /**
  26.          *        当某块下载完成的时候
  27.          *  @param blockNum 块号
  28.          *  @param readBytes 下载完成的字节
  29.          */
  30.         void onBlockCompleted(int blockNum, long readBytes);
  31.         
  32.         /**
  33.          * 下载速度
  34.          * @param speed 下载速度
  35.          */
  36.         void onDownLoadSpeed(long speed);
  37. }
复制代码

3: 多线程下载控制类
  1. package com.eibit.javalearning;

  2. import java.io.BufferedInputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.RandomAccessFile;
  8. import java.net.HttpURLConnection;
  9. import java.net.MalformedURLException;
  10. import java.net.URL;
  11. import java.util.LinkedList;
  12. import java.util.concurrent.ExecutorService;
  13. import java.util.concurrent.Executors;

  14. import javax.net.ssl.HttpsURLConnection;

  15. /**
  16. * 文件下载管理类
  17. */
  18. public class ThreadPoolMultiDownLoadManager {
  19.         private String path; //资源的原始路径比如说是http://dlsw.baidu.com/sw-search-sp/soft/ea/12585/mysql-5.6.24-win32.1432006610.zip
  20.         private String targetFile; //下载的文件存储的目标地址
  21.         private DownListener downListener; //下载的监听器
  22.     
  23.     private static long blockSize = 1 * 1024 * 1024; //每块的大小,默认是1MB

  24.         //最大线程数量
  25.         private int MAX_THREAD_NUM = 5; //线程池的线程的数量

  26.     private long fileSize; //文件的总大小
  27.         //private long mTotalDownloadedBytes = 0; //总的已下载的字节数
  28.         private long mLastDownloadedTime = 0; //上次的已下载的字节数的时间,为毫秒,主要用于下载速度的
  29.         private int lastDownloadPercent = 0; //上次下载的百分比,主要是用于计算下载的百分比的
  30.         //固定容量大小的线程池
  31.         private ExecutorService executorService;

  32.         private final Object mLock = new Object(); //用于块队列的同步的锁,不能让一块文件被两个线程下载
  33.         //private final Object lock = new Object(); //用于计算下载百分比同步锁
  34.         private LinkedList<BlockBean> mQueue = new LinkedList<BlockBean>(); //块队列
  35.         private int mCompletedBlock = 0; //已完成的块数
  36.         private int blockCount = 0; //总的块数
  37.         private int mCompletedThreadCount = 0; //已完成的线程的数量,用于统计是否下载结束
  38.         private long mDeltaDownLoadedBytes = 0; //单位时间内下载的字节数

  39.         /**
  40.          * 构造器
  41.          * @param path 资源路径
  42.          * @param targetFile 目标文件的存放地址
  43.          * @param downListener 下载监听器
  44.          */
  45.         public ThreadPoolMultiDownLoadManager(String path, String targetFile, DownListener downListener){
  46.                 this.path = path;
  47.                 this.targetFile = targetFile;
  48.                 this.downListener = downListener;
  49.         }
  50.         
  51.         /**
  52.          * 开启多线程下载
  53.          */
  54.         public void multiDownload(){
  55.                 //初始化,进行清零操作
  56.                 lastDownloadPercent = 0;
  57.                 //mTotalDownloadedBytes = 0;
  58.                 mCompletedBlock = 0;
  59.                 mCompletedThreadCount = 0;
  60.                 //初始化线程池
  61.                 executorService = Executors.newFixedThreadPool(MAX_THREAD_NUM);
  62.                 //执行一个任务
  63.                 //executorService.execute(new GetContentThread());
  64.                 new Thread(new GetContentThread()).start(); //不把这个任务放到线程池里面去
  65.         }
  66.         
  67.         /**
  68.          * 获取文件的大小和属性的一个总控线程
  69.          */
  70.         private class GetContentThread implements Runnable {
  71.                 @Override
  72.                 public void run() {
  73.                         //开始下载
  74.                         if(downListener != null) {
  75.                                 downListener.onStartDownLoad();
  76.                         }
  77.                         doDownload(path, targetFile);
  78.                 }
  79.         }
  80.         
  81.         /**
  82.          * 计算文件大小, 并开启线程下载
  83.          * @param path 资源的url地址
  84.          * @param targetFile 资源本地存放路径
  85.          */
  86.         private void doDownload(String path, String targetFile){
  87.                 try {
  88.                         HttpURLConnection httpConnection = (HttpURLConnection) new URL(path).openConnection();
  89.                         //只获取文件的响应报头,而不获取文件的内容,这个响应报头里面就会包含文件大小等信息
  90.                         httpConnection.setRequestMethod("HEAD");
  91.                         httpConnection.connect();

  92.                         int responseCode = httpConnection.getResponseCode();
  93.                         System.out.println("---------------------------------------responseCode=" + responseCode);
  94.                 if(responseCode >= 400){
  95.                     System.out.println("Web服务器响应错误!");
  96.                     return;
  97.                 }
  98.                         httpConnection.disconnect();
  99.                         if(responseCode == HttpsURLConnection.HTTP_OK) { //服务器响应成功
  100.                                 //获取文件的大小
  101.                                 fileSize = httpConnection.getContentLength(); 
  102.                                 if(fileSize <0) { //使用HEAD获取不到文件大小
  103.                                         UnKnownSizeSingleDowloadThread thread = new UnKnownSizeSingleDowloadThread(path, targetFile);
  104.                                         executorService.execute(thread);
  105.                                         executorService.shutdown();
  106.                                 } else { //可以获取到文件的大小
  107.                                         //生成文件
  108.                                         File newFile = new File(targetFile);
  109.                                         //生成一个可以随机存取的文件RandomAccessFile,以读写的方式打开
  110.                                         RandomAccessFile raf = new RandomAccessFile(newFile, "rw");
  111.                                         raf.setLength(fileSize); //设置这个文件大小
  112.                                         raf.close(); //关闭这个文件

  113.                                         blockCount = 0; //块的数量
  114.                                         //计算有多少个块
  115.                                         if(fileSize % blockSize == 0) {
  116.                                                 blockCount = (int) (fileSize / blockSize);
  117.                                         } else {
  118.                                                 blockCount = (int)(fileSize /blockSize) + 1;
  119.                                         }
  120.                                         System.out.println("Block Count = "+ blockCount);
  121.                                         
  122.                                         mLastDownloadedTime = System.currentTimeMillis(); //初始化第一次下载时间为毫秒级
  123.                                         //再小实际上都可以用块进行下载,可以将其判断去掉
  124.                                         if(blockCount <=5 ){ //如果块的数量小于5块,没必要使用多线程进行下载
  125.                                                 SingleDowloadThread singleDowloadThread = new SingleDowloadThread(path, targetFile, fileSize);
  126.                                                 executorService.execute(singleDowloadThread);
  127.                                                 executorService.shutdown(); //关闭线程池
  128.                                         } else  { //如果块的数量大于5块,则开启多线程下载
  129.                                                 //初始化块的队列
  130.                                                 long offset = 0;
  131.                                                 for(int i=0; i< blockCount; i++) {
  132.                                                         //最后的一块需要特殊对待,因为最后一块的大小可能没有blockSize这么大
  133.                                                         if(i == blockCount -1) {
  134.                                                                 BlockBean bean = new BlockBean(i, offset, fileSize-offset);
  135.                                                                 offset += blockSize;
  136.                                                                 mQueue.add(bean);
  137.                                                         } else {
  138.                                                                 BlockBean bean = new BlockBean(i, offset, blockSize);
  139.                                                                 offset += blockSize;
  140.                                                                 mQueue.add(bean);
  141.                                                         }
  142.                                                 }
  143.                                                 //使用线程池进行操作
  144.                                                 for(int i = 0; i< MAX_THREAD_NUM; i++) {
  145.                                                         DownloadTask task = new DownloadTask(path, targetFile);
  146.                                                         executorService.execute(task);
  147.                                                 }
  148.                                                 executorService.shutdown();
  149.                                         }
  150.                                 }
  151.                         }
  152.                 } catch (MalformedURLException e) {
  153.                         e.printStackTrace();
  154.                 } catch (IOException e) {
  155.                         e.printStackTrace();
  156.                 }
  157.         }
  158.     
  159.     /**
  160.      * 负责文件下载的类
  161.      */
  162.     private class DownloadTask implements Runnable {
  163.         private String url = null;
  164.         private String fileName = null;

  165.         protected DownloadTask(String url, String fileName) {
  166.                         this.url = url;
  167.                         this.fileName = fileName;
  168.         }
  169.      
  170.         public void run() {
  171.                         boolean flag = false; //是否还有块没有下载完成
  172.                         while(!flag) {
  173.                                 BlockBean block = null;
  174.                                 //首先去查找还有没有块已完成
  175.                                 synchronized (mLock) {
  176.                                         if(mQueue.size() > 0) {
  177.                                                 //取一块出来
  178.                                                 block = mQueue.remove(); 
  179.                                         }
  180.                                 }
  181.                                 
  182.                                 //测试代码
  183.                                 /*if(block != null) {
  184.                                         System.out.println("block=" + block.i + ", \tThread Number=" + Thread.currentThread().getName());
  185.                                         try {
  186.                                                 Thread.sleep(200);
  187.                                         } catch (InterruptedException e) {
  188.                                                 e.printStackTrace();
  189.                                         }
  190.                                         
  191.                                         if(block.i % 20 == 0) {
  192.                                                 System.out.println("IOException block =" + block.i);
  193.                                                 synchronized (lock) {
  194.                                                         if(block.tryCount++ < BlockBean.MAX_TRY_COUNT) { //如果还没有达到最大的尝试次数,那么就接着继续下载
  195.                                                                 mQueue.add(block); //把这一块重新加到队列里面去
  196.                                                         }
  197.                                                 }
  198.                                         }
  199.                                 } else {
  200.                                         flag = true;
  201.                                 }*/
  202.                                  
  203.                                 if(block != null) { //还有块没有下载完成
  204.                                         long offset = block.offset;
  205.                                         long length = block.length;
  206.                                         int i = block.i;
  207.                                         //long mLastDownloadedTime = System.currentTimeMillis();
  208.                                         //System.out.println("downLoad block i=" + i + " finished");
  209.                                         try {
  210.                                                 HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
  211.                                                 httpConnection.setRequestMethod("GET");
  212.                                                 httpConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg,*/*");
  213.                                                 httpConnection.setRequestProperty("Accept-Language", "zh_CN");
  214.                                                 httpConnection.setRequestProperty("Charset", "UTF-8");
  215.                                                 httpConnection.setRequestProperty("User-Agent", "Mozilla/4.0(compatible; MSIE 7.0; Windows NT 5.2;)");
  216.                                                 httpConnection.setRequestProperty("Connection", "Keep-Alive"); 
  217.                                                 //设置RANGE属性,向服务器请求,其中的某一段数据
  218.                                                 httpConnection.setRequestProperty("RANGE", "bytes=" + offset + "-" + (offset + length - 1));
  219.                                                 httpConnection.setConnectTimeout(15000); //15秒的连接超时
  220.                                                 httpConnection.setReadTimeout(30000);//30秒的读写超时,连接和读写超时跟网络状态有关
  221.                                                 int responseCode = httpConnection.getResponseCode();
  222.                                                 if(responseCode == HttpURLConnection.HTTP_PARTIAL) { //部分内容
  223.                                                         BufferedInputStream bis = new BufferedInputStream(httpConnection.getInputStream());
  224.                                                         byte[] buffer = new byte[1024];
  225.                                                         int readedBytes = 0;
  226.                                                         File newFile = new File(fileName);
  227.                                                         RandomAccessFile raf = new RandomAccessFile(newFile, "rw");
  228.                                                         raf.seek(offset); //跳转到文件的指定位置
  229.                                                         while((readedBytes = bis.read(buffer,0, buffer.length)) != -1) {
  230.                                                                 raf.write(buffer, 0, readedBytes);
  231.                                                                 //currentDownloadBytes += readedBytes;
  232.                                                         }
  233.                                                         raf.close();
  234.                                                         bis.close();
  235.                                                         httpConnection.disconnect();
  236.                                                         mDeltaDownLoadedBytes+= length; //单位时间内下载的字节数增加

  237.                                                         //以下代码已经废弃
  238.                                                         /*synchronized (lock) {
  239.                                                                 mTotalDownloadedBytes += length;
  240.                                                                 //计算现在速度
  241.                                                                 long currentTime = System.currentTimeMillis();
  242.                                                                 //速度是多少KB/s
  243.                                                                 long speed = (long) (length / ((currentTime - mLastDownloadedTime) /1000.0) /1024);
  244.                                                                 mLastDownloadedTime = currentTime; //重新初始化时间
  245.                                                                 
  246.                                                                 //计算下载的百分比
  247.                                                                 int downloadPercent = (int) (mTotalDownloadedBytes * 100 / fileSize);
  248.                                                                 //System.out.println("mTotalDownloadedBytes=" + mTotalDownloadedBytes + ",fileSize=" + fileSize + ",downloadPercent=" + downloadPercent);
  249.                                                                 if(downloadPercent -lastDownloadPercent >= 1) {//百分之百可能不通知
  250.                                                                         //保证每次更新进展值都大于1,避免更新太过于频繁
  251.                                                                         lastDownloadPercent = downloadPercent;
  252.                                                                         if(downListener != null) {
  253.                                                                                 downListener.onCompleteRateChanged(downloadPercent,speed);
  254.                                                                         }
  255.                                                                 }
  256.                                                                 if(downloadPercent == 100) {
  257.                                                                         if(downListener != null) {
  258.                                                                                 downListener.onCompleteRateChanged(downloadPercent, speed);
  259.                                                                         }
  260.                                                                 }
  261.                                                         }*/
  262.                                                         if(downListener != null) {
  263.                                                                 downListener.onBlockCompleted(i, length);
  264.                                                                 synchronized (mLock) {
  265.                                                                         mCompletedBlock++; //已完成的块加1
  266.                                                                         int percent = mCompletedBlock  * 100 / blockCount;
  267.                                                                         downListener.onCompleteRateChanged(percent);
  268.                                                                         long currentTime = System.currentTimeMillis();
  269.                                                                         
  270.                                                                         if((currentTime - mLastDownloadedTime ) /1000 > 1) {//时间差不到1秒不要去计算速度
  271.                                                                                 //速度是多少KB/s
  272.                                                                                 long speed = (long) (mDeltaDownLoadedBytes / ((currentTime - mLastDownloadedTime) /1000.0) /1024);
  273.                                                                                 mDeltaDownLoadedBytes = 0; //清空单位时间内下载的字节数
  274.                                                                                 mLastDownloadedTime = currentTime; //重新初始化时间
  275.                                                                                 downListener.onDownLoadSpeed(speed);
  276.                                                                         }
  277.                                                                 }
  278.                                                         }
  279.                                                 }
  280.                                         } catch (IOException e) {
  281.                                                 e.printStackTrace();
  282.                                                 //如果出现IO异常,则表示这一块的数据没有完整的下载下来
  283.                                                 //那么将进行一次重新下载
  284.                                                 synchronized (mLock) {
  285.                                                         System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<< IOException blockNumber:" + i + "<<<<<<<<<<<<<<<<<<<<<<<<");
  286.                                                         blockCount++; //出现异常一次,需要下载的块的数量加1
  287.                                                         if(block.tryCount++ < BlockBean.MAX_TRY_COUNT) { //如果还没有达到最大的尝试次数,那么就接着继续下载
  288.                                                                 mQueue.add(block); //把这一块重新加到队列里面去
  289.                                                         }
  290.                                                 }
  291.                                         }
  292.                                 } else {//没有块可供下载,则结束掉当前线程
  293.                                         flag = true;
  294.                                         break;
  295.                                 }
  296.                         }
  297.                         /*if(mTotalDownloadedBytes >= totalLength && downListener != null) { //下载结束
  298.                                 downListener.onDownloadCompleted(targetFile);
  299.                         }*/
  300.                         System.out.println("------------------------------"+ Thread.currentThread().getName() + "----------------------" );
  301.                         synchronized (mLock) {
  302.                                 mCompletedThreadCount++; //已完成的线程数量加1
  303.                                 if(downListener != null){
  304.                                         if(mCompletedThreadCount == MAX_THREAD_NUM){ //已完成的线程数如果大于等于线程池的大小,则下载完成
  305.                                                 downListener.onDownloadCompleted(fileName);
  306.                                         }
  307.                                 }
  308.                         }
  309.         }
  310.     }
  311.     
  312.     private class SingleDowloadThread implements Runnable{
  313.             private String url = null;
  314.         private String fileName = null;
  315.         private long fileSize = 0; //下载的总长度
  316.         
  317.         public SingleDowloadThread(String url, String fileName, long fileSize) {
  318.                 this.url = url;
  319.                 this.fileName = fileName;
  320.                 this.fileSize = fileSize;
  321.                 }
  322.         
  323.                 @Override
  324.                 public void run() {
  325.                         HttpURLConnection httpConnection;
  326.                         try {
  327.                                 httpConnection = (HttpURLConnection) new URL(url).openConnection();
  328.                                 httpConnection.setRequestMethod("GET");
  329.                                 httpConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg,*/*");
  330.                                 httpConnection.setRequestProperty("Accept-Language", "zh_CN");
  331.                                 httpConnection.setRequestProperty("Charset", "UTF-8");
  332.                                 httpConnection.setRequestProperty("User-Agent", "Mozilla/4.0(compatible; MSIE 7.0; Windows NT 5.2;)");
  333.                                 httpConnection.setRequestProperty("Connection", "Keep-Alive"); 
  334.                                 httpConnection.setConnectTimeout(15000); //15秒的连接超时
  335.                                 httpConnection.setReadTimeout(30000);//30秒的读写超时
  336.                                 int responseCode = httpConnection.getResponseCode();
  337.                                 if(responseCode == HttpURLConnection.HTTP_OK) {
  338.                                         InputStream inputStream = httpConnection.getInputStream();
  339.                                         FileOutputStream outputStream = new FileOutputStream(fileName);
  340.                                         byte[] buffer = new byte[1024];
  341.                                         int len = -1;
  342.                                         long readedBytes = 0;
  343.                                         long deltaReadBytes = 0; //在1秒的时间间隔之内,下载的字节数
  344.                                         //long mLastDownloadedTime = System.currentTimeMillis();
  345.                                         while( (len = inputStream.read(buffer, 0, buffer.length)) != -1) {
  346.                                                 outputStream.write(buffer, 0, len);
  347.                                                 readedBytes += len; 
  348.                                                 deltaReadBytes += len;
  349.                                                 
  350.                                                 long currentTime = System.currentTimeMillis();
  351.                                                 //System.out.println("currentTime - mLastDownloadedTime=" + (currentTime - mLastDownloadedTime) + "len=" + len);
  352.                                                 if((currentTime - mLastDownloadedTime ) /1000 > 1) {//时间差不到1秒不要去计算速度
  353.                                                         long speed = (long) (deltaReadBytes / ((currentTime - mLastDownloadedTime) / 1000.0) /1024);
  354.                                                         deltaReadBytes = 0; //计算了速度之后,需要对deltaReadBytes清零
  355.                                                         mLastDownloadedTime = currentTime; 
  356.                                                         if(downListener != null) {
  357.                                                                 downListener.onDownLoadSpeed(speed);
  358.                                                         }
  359.                                                 }
  360.                                                 //计算百分比
  361.                                                 int percent = (int) (readedBytes * 100 / fileSize);
  362.                                                 if(downListener != null) {
  363.                                                         if(percent - lastDownloadPercent >= 1) {
  364.                                                                 downListener.onCompleteRateChanged(percent);
  365.                                                         }
  366.                                                 }
  367.                                         }
  368.                                         if(downListener != null) {
  369.                                                 downListener.onDownloadCompleted(fileName);
  370.                                         }
  371.                                         inputStream.close();
  372.                                         outputStream.close();
  373.                                 }
  374.                         } catch (MalformedURLException e) {
  375.                                 e.printStackTrace();
  376.                         } catch (IOException e) {
  377.                                 e.printStackTrace();
  378.                         }
  379.                 }
  380.             
  381.     }
  382.     
  383.     private class UnKnownSizeSingleDowloadThread implements Runnable{
  384.             private String url = null;
  385.         private String fileName = null;
  386.         
  387.         public UnKnownSizeSingleDowloadThread(String url, String fileName) {
  388.                 this.url = url;
  389.                 this.fileName = fileName;
  390.                 }
  391.         
  392.                 @Override
  393.                 public void run() {
  394.                         HttpURLConnection httpConnection;
  395.                         try {
  396.                                 httpConnection = (HttpURLConnection) new URL(url).openConnection();
  397.                                 httpConnection.setRequestMethod("GET");
  398.                                 httpConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg,*/*");
  399.                                 httpConnection.setRequestProperty("Accept-Language", "zh_CN");
  400.                                 httpConnection.setRequestProperty("Charset", "UTF-8");
  401.                                 httpConnection.setRequestProperty("User-Agent", "Mozilla/4.0(compatible; MSIE 7.0; Windows NT 5.2;)");
  402.                                 httpConnection.setRequestProperty("Connection", "Keep-Alive"); 
  403.                                 httpConnection.setConnectTimeout(15000); //15秒的连接超时
  404.                                 httpConnection.setReadTimeout(30000);//30秒的读写超时
  405.                                 int responseCode = httpConnection.getResponseCode();
  406.                                 if(responseCode == HttpURLConnection.HTTP_OK) {
  407.                                         InputStream inputStream = httpConnection.getInputStream();
  408.                                         FileOutputStream outputStream = new FileOutputStream(fileName);
  409.                                         byte[] buffer = new byte[1024];
  410.                                         int len = -1;
  411.                                         long deltaReadBytes = 0; //在1秒的时间间隔之内,下载的字节数
  412.                                         //long mLastDownloadedTime = System.currentTimeMillis();
  413.                                         while( (len = inputStream.read(buffer, 0, buffer.length)) != -1) {
  414.                                                 outputStream.write(buffer, 0, len);
  415.                                                 deltaReadBytes += len;
  416.                                                 
  417.                                                 long currentTime = System.currentTimeMillis();
  418.                                                 //System.out.println("currentTime - mLastDownloadedTime=" + (currentTime - mLastDownloadedTime) + "len=" + len);
  419.                                                 if((currentTime - mLastDownloadedTime ) /1000 > 1) {//时间差不到1秒不要去计算速度
  420.                                                         long speed = (long) (deltaReadBytes / ((currentTime - mLastDownloadedTime) / 1000.0) /1024);
  421.                                                         deltaReadBytes = 0; //计算了速度之后,需要对deltaReadBytes清零
  422.                                                         mLastDownloadedTime = currentTime; 
  423.                                                         if(downListener != null) {
  424.                                                                 downListener.onDownLoadSpeed(speed);
  425.                                                         }
  426.                                                 }
  427.                                                 //大小未知,无法计算百分比
  428.                                         }
  429.                                         if(downListener != null) {
  430.                                                 downListener.onDownloadCompleted(fileName);
  431.                                         }
  432.                                         inputStream.close();
  433.                                         outputStream.close();
  434.                                 }
  435.                         } catch (MalformedURLException e) {
  436.                                 e.printStackTrace();
  437.                         } catch (IOException e) {
  438.                                 e.printStackTrace();
  439.                         }
  440.                 }
  441.             
  442.     }
  443. }
复制代码


4: 下载程序测试主类。
  1. package com.eibit.javalearning;

  2. /**
  3. * Created by Administrator on 2016/4/16.
  4. */
  5. public class TestMultiDownload implements  DownListener{

  6.     public static void main(String[] args) {
  7.         String URL = "http://123.147.165.57:9999/dlsw.baidu.com/sw-search-sp/soft/ea/12585/mysql-5.6.24-win32.1432006610.zip";
  8.         String TARGET_FILE ="E:\\mysql-5.6.24-win32.1432006610.zip";
  9.         TestMultiDownload download = new TestMultiDownload();
  10.         ThreadPoolMultiDownLoadManager downLoadManager = new ThreadPoolMultiDownLoadManager(URL, TARGET_FILE, download);
  11.         downLoadManager.multiDownload();
  12.     }

  13.     @Override
  14.     public void onStartDownLoad() {
  15.         System.out.println("************ onStartDownLoad **************");
  16.     }

  17.     @Override
  18.     public void onCompleteRateChanged(int completeRate) {
  19.         System.out.println("************ onCompleteRateChanged completeRate= " + completeRate);
  20.     } 

  21.     @Override
  22.     public void onDownloadCompleted(String fileName) {
  23.         System.out.println("----------------------- onDownloadCompleted  fileName = " + fileName + "-------------------");
  24.     }

  25.     @Override
  26.     public void onStartMultiDownLoad(int numberThread) {
  27.         System.out.println("----------------------- onStartMultiDownLoad  numberThread = " + numberThread + "-------------------");
  28.     }

  29.     @Override
  30.     public void onBlockCompleted(int blockNum, long readBytes) {
  31.         System.out.println("----------------------- onBlockCompleted  BlockNum = " + blockNum + ",readBytes=" + readBytes + "-------------------");
  32.     }

  33.         @Override
  34.         public void onDownLoadSpeed(long speed) {
  35.                 System.out.println("----------------------- onDownLoadSpeed  speed=" + speed + " KB/s");
  36.         }
  37. }
复制代码

匆忙之间写下的程序,其中肯定有不足之处。欢迎大家不吝赐教!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值