1、多线程介绍

用过迅雷的同学都知道。迅雷有个功能叫做多线程。另一个叫离线下载,我们这里重点介绍一下多线程下载。多线程,顾名思义就是非常多歌线程同一时候在执行,为什么要提出多线程这个概念呢?由于有时候一个线程下载太慢了。举个样例,比方小时候常做的数学题,一个人挖沟须要15天,那么两个人对着挖呢?

当然数学题上面两个人的效率是不一样的,我们这里把这个问题简化了一下。仅仅是想大家明确,什么是多线程,为什么有多线程。

在多线程上出现过一个问题,为什么有要提出多线程?事实上提出多线程是为了充分利用CPU的硬件资源,解决应用程序等待的问题。多线程是为了同步完毕多项任务,不是为了提高执行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间须要完毕多项任务的时候实现的。

2、思路

(1)获取网络连接

(2)初始化多线程下载信息,開始下载

(3)开辟硬盘空间,用于存放数据资源

(4)把从网络获取的数据放入申请的空间中

(5)完成下载,关闭资源链接

给出一个下载400M电影的示意图,例如以下所看到的:

RandomAccessFile支持随机的訪问

HTTP的Range头字段指定每一个线程从文件的什么位置開始下载。

3、代码解析

3.1 设置须要下载文件的信息

  1. RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rwd");
  2. if(this.fileSize>0){
  3. randOut.setLength(this.fileSize);//设置文件的大小
  4. }
  5. randOut.close(); //关闭该文件,使设置生效

3.2 设置下载链接,而且開始划分下载部分

  1. URL url = new URL(this.downloadUrl);
  2. if(this.data.size() != this.threads.length){ //假设原先未曾下载或者原先的下载线程数与如今的线程数不一致
  3. this.data.clear(); //将数据置空
  4. for (int i = 0; i < this.threads.length; i++) { //遍历线程池
  5. this.data.put(i+1, 0);//初始化每条线程已经下载的数据长度为0
  6. }
  7. this.downloadedSize = 0; //设置已经下载的长度为0
  8. }

3.3 開始下载文件

  1. for (int i = 0; i < this.threads.length; i++) {
  2. //通过特定的线程ID获取该线程已经下载的数据长度
  3. int downloadedLength = this.data.get(i+1);
  4. //推断线程是否已经完毕下载,否则继续下载
  5. if(downloadedLength < this.block && this.downloadedSize < this.fileSize){
  6. //初始化特定id的线程
  7. this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
  8. //设置线程的优先级,Thread.NORM_PRIORITY = 5 Thread.MIN_PRIORITY = 1 Thread.MAX_PRIORITY = 10
  9. this.threads[i].setPriority(7);
  10. //启动线程
  11. this.threads[i].start();
  12. }else{
  13. this.threads[i] = null; //表明在线程已经完毕下载任务
  14. }
  15. }

3.4 监听文件是否下载完毕以及完毕之后的操作

  1. fileService.delete(this.downloadUrl); //假设存在下载记录,删除它们。然后又一次加入
  2. fileService.save(this.downloadUrl, this.data); //把已经下载的实时数据写入数据库

  1. boolean notFinished = true;//下载未完毕
  2. // 循环推断所有线程是否完毕下载
  3. while (notFinished) {
  4. notFinished = false;//假定所有线程下载完毕
  5. for (int i = 0; i < this.threads.length; i++){
  6. if (this.threads[i] != null && !this.threads[i].isFinished()) {//假设发现线程未完毕下载
  7. notFinished = true;//设置标志为下载没有完毕
  8. //假设下载失败,再又一次在已经下载的数据长度的基础上下载
  9. if(this.threads[i].getDownloadedLength() == -1){
  10. //又一次开辟下载线程。代码与上面一致
  11. }
  12. }
  13. }
  14. if(listener!=null){
  15. listener.onDownloadSize(this.downloadedSize);
  16. }//通知眼下已经下载完毕的数据长度
  17. }
  18.  
  19. //下载完毕删除记录
  20. if(downloadedSize == this.fileSize){
  21. fileService.delete(this.downloadUrl);
  22. }

4、断点续传

断点续传是说在下载的时候,我们由于某些原因,导致了下载的暂停。比方在电脑上,我们的电脑突然断电了,手机上的网络中断了,都会导致当前的下载任务终止,那么当我们再次回来的时候。程序应该是能够继续下载的,不然前面下载的资源就都浪费了。

依据上面的描写叙述。我们应该能够知道。实现断点续传,关键是实现下载的数据存储在数据库中,等到之后我们程序再次进入的时候,会到数据库中去查询一下数据。然后接着继续下载。

而存储数据到数据库并非太复杂,难的是怎样识别程序的哪些数据被下载了。哪些数据是没有下载的。这里,我们在下载的时候使用了下载的线程id做识别。

        假设该线程id的数据没有被完整下载。应该是不会存储到数据库的,那么这一部分的数据就要又一次下载,在下载完毕之后,数据拼接起来就是一个完整的文件了。

Android多线程下载大文件解析的更多相关文章

  1. Android 开发工具类 27_多线程下载大文件

    多线程下载大文件时序图 FileDownloader.java package com.wangjialin.internet.service.downloader; import java.io.F ...

  2. Andoid 更好的Android多线程下载框架

    概述 为什么是更好的Android多线程下载框架呢,原因你懂的,广告法嘛! 本篇我们我们就来聊聊多线程下载框架,先聊聊我们框架的特点: 多线程 多任务 断点续传 支持大文件 可以自定义下载数据库 高度 ...

  3. 更好的Android多线程下载框架

    /** * 作者:Pich * 原文链接:http://me.woblog.cn/ * QQ群:129961195 * Github:https://github.com/lifengsofts */ ...

  4. 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)

    1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...

  5. android程序---->android多线程下载(一)

    多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次 ...

  6. android程序---->android多线程下载(二)

    上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序--- ...

  7. 转(Response.WriteFile 无法下载大文件解决方法)

    以前用Response.WriteFile(filename),但当遇到大文件时无法完整下载. 该方法最大的问题,它不是直接将数据抛到客户端,而是在服务器端(IIS)上缓存.当下载文件比较大时,服务器 ...

  8. JAVA多线程下载网络文件

    JAVA多线程下载网络文件,开启多个线程,同时下载网络文件.   源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...

  9. python下载大文件

    1. wget def download_big_file_with_wget(url, target_file_name): """ 使用wget下载大文件 Note: ...

随机推荐

  1. 九度oj 题目1459:Prime ring problem

    题目描述: A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each ...

  2. 【Luogu】P2254瑰丽华尔兹(堆优化DP)

    题目链接 我也不知道为什么脑子一抽就想了个堆优化……然后贼慢…… 因为上午听不懂wys的电音专场(快速傅立叶变换),然后就做了这么一道题. 首先朴素DP很sb都能秒出.就是枚举时刻.位置(两维)然后转 ...

  3. 【Luogu】P2602数字计数(数位DP)

    题目链接 数位DP好喵啊.自己yy两个小时的dfs:题解40行代码=10WA:10A. md而且还不是完全理解题解是什么意思. 所以放题解链接. #include<cstdio> #inc ...

  4. 【Luogu】P3343地震后的幻想乡(对积分概率进行DP)

    题目链接 神难qwq.配合rqy的博客食用. 首先我们学到有一个概率函数$p(x)$表示某事件发生概率取值小于x的函数.这个函数有什么特点呢? 那就是$\int_{-∞}^{∞}p(x)dx=1$ 这 ...

  5. ACM程序设计选修课——1051: Glamor Sequence(YY+求和公式)

    1051: Glamor Sequence Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 16  Solved: 5 [Submit][Status] ...

  6. 【bzoj1257】[CQOI2007]余数之和sum

    [bzoj1257][CQOI2007]余数之和sum 2014年9月1日1,9161 Description 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod ...

  7. Docker 使用指南—— 基本操作

    版权声明:本文由田飞雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/98来源:腾云阁 https://www.qcloud ...

  8. linux内核学习之四:进程切换简述【转】

    转自:http://www.cnblogs.com/xiongyuanxiong/p/3531884.html 在讲述专业知识前,先讲讲我学习linux内核使用的入门书籍:<深入理解linux内 ...

  9. poj 3204(最小割--关键割边)

    Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7 ...

  10. LeetCode OJ--Next Permutation *

    求一个排列的下一个排列. 1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1 #include <iostream> #include <vector&g ...