java_多线程下载

原理:

多线程下载,故名思意,就是开启多个线程去下载文件,每个线程负责一部分。

实现有两种方式:

1、多个线程同时下载同时对同一个文件进行写的操作,也就是说,获取了文件的总长度后在本地生成一个大小一致的文件,然后每个线程分别对这个文件进行边下载边写。

例如:一个文件总大小是6M,分3个线程去下载,那么本地也先生成一个大小为6M的文件,然后3个线程一边下载一边的对文件进行写,不同的是,线程1从0的位置开始写,线程2从2*1024*1024的位置开始写,线程3是从4*1024*1024的位置开始写!全部线程下载完毕后,文件也就下载完毕了!

2、还是和第一种方式一样,分段下载。还是上面那个例子,3个线程分别生成一个文件(这个文件不需要事先指定大小),然后下载完后拼接成一个文件,就这么简单。

两种方式,都需要搞清楚的是:每个线程从哪里开始读?这点要清楚,如果每一个都从开始的位置读的话,那就挂了。还有一点就是,下载的时候,不是第一个线程要跳到指定位置开始下载,不然全部下载回来的都是第一段,有毛用?

两种方式的比较,第一种其实是比较方便的,只需要注意每个线程从哪里开始写,写,写。就可以了。第二种,代码量多一点,然后还有一个难点是:最后一步合并文件,合并文件本身没什么难度,难的是什么时候合并?只有所有的线程都下载完毕的时候才合并,不然就瞎掰了!哈哈


下面来看代码,纯java的代码!

本demo不怎么具备实用性!(因为没监听下载完毕的动作,给个思路,可以给每个线程下载完毕的时候加个回调)

先来看看单线程下载:

这里说明一下,line200-212是最初的方式,下载全部。line214-233是另一种方式,也就是接下来我们要做的,下载指定的段。这里当然是下载文件从头到尾了!


下面来看下载的线程的代码:

代码注释也可以看清楚了,这里不再解释;


最终的下载代码,分段下载


这里虽然联网,只是获取文件的总大小,不进行下载,获取总大小后,计算出每一段的大小。

然后分割。

这里看每个线程需要的4个参数,第一个地址,第二个是线程ID,这两个都没什么好解释的了,然后第三个,开始位置,开始位置我这里直接 * i  因为 i=0 的时候也对嘛,直接从0(文件头部)开始下载,最后一个参数,这里就直接 * i+1 咯,差不多是这样,我这里有个判断,如果是最后一个线程,那么就直接给0(因为我下载线程那里做了判断,如果结尾是0的话就直接下载到文件尾部),这里也可以传文件的总大小,也是对的,但就不能不判断,直接传 section * (i+1) 因为大家都知道,不管long还是int,当不整除的时候,是会丢的。例如,一个文件大小为10,分3个线程下载,如果不判断的话,分别下载0-3,3-6,6-9,自己拿着手指头数一数,你总共下载了9,而总大小是10,你说对不对?你去打开一下这样的文件,看能不能打开?(前提不要是文本文件,文本文件估计可以打开,哈哈!)


最后一步,合并文件:



好了,先到这里,后续再对这个进行升级。


线程篇:

Java_线程-Thread

Java_线程—经典的例子:售票

Java_线程—经典的例子:生产者和消费者


java_多线程下载


1.得到服务器下载文件的大小,然后在本地设置一个临时文件和服务器端文件大小一致 a)获得访问网络地址 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout iii.setReadTimeout d)判断是否响应成功 e)获取文件长度(getContentLength()) f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)设置临时文件与服务器文件大小一致(setLength()) h)关闭临时文件 2.计算出每个线程下载的大小(开始位置,结束位置) a)计算出每个线程下载的大小 b)for循环,计算出每个线程的开始、结束位置 c)最后一个线程处理 3.每创建好一次就要开启线程下载 a)构造方法 b)通过URL对象的openConnection()方法打开连接,返回一个连接对象 c)设置请求头 i.setRequestMethod ii.setConnectTimeout d)判断是否响应成功(206) e)获取每个线程返回的流对象 f)随机访问文件的读取与写入RandomAccessFile(file, mode) g)指定开始位置 h)循环读取 i.保存每个线程下载位置 ii.记录每次下载位置 iii.关闭临时记录位置文件 iv.随机本地文件写入 v.记录已下载大小 i)关闭临时文件 j)关闭输入流 4.为了杀死线程还能继续下载的情况下,从本地文件上读取已经下载文件的开始位置 a)创建保存记录结束位置的文件 b)读取文件 c)将流转换为字符 d)获取记录位置 e)把记录位置赋给开始位置 5.当你的n个线程下载完毕的时候我进行删除记录下载位置的缓存文件 a)线程下载完就减去 b)当没有正在运行的线程时切文件存在时删除文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值