Java:使用多线程实现文件分区间下载

每日一讲

我不知道我应当成为一个什么样的人,但我知道我应当不成为什么样的人!

目录

每日一讲

1.多线程文件分区下载目的和原理

2.多线程文件下载的实现过程

2.1获取下载文件的大小

2.2计算每个线程需要下载的范围

2.3创建线程进行下载任务

2.4在线程内进行读写操作实现文件下载

3.文件合成

3.1创建新类MergeFile合并文件

3.2创建CountDownLatch类及调用MergeFile类

 3.3改善线程个数和下载地址写死问题

4.完整代码和运行结果

4.1运行结果

4.2完整代码


1.多线程文件分区下载目的和原理

目的:正常我们下载文件通常是一下到底,只使用一个线程进行下载。但是通常情况下使用多个线程下载的效率会更高,迅雷下载中也是推荐使用三个线程进行下载,当然这也取决于网络,网络不好,线程多也未必是好事。

原理:将一个文件分成多端进行下载,每个线程下载文件的一部分,就好比一个苹果咱们三个好基友一起吃。用这么一张图就能很好的了解了。

2.多线程文件下载的实现过程

实际上想要实现简单的多线程任务设计的技术不难,但也有许多,比如多线程、I/O流、参数传递、构造函数、类和对象等等。

文件链接:https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.7_240305_x64_01.exe

2.1获取下载文件的大小

要分区间下载我们就必然要文件的总大小,才能更好的分配嘛。

URL url =new URL(address);
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
long fileSize=httpURLConnection.getContentLengthLong();//获取要下载文件的大小
System.out.println("文件大小为:"+fileSize);

2.2计算每个线程需要下载的范围

既然大厨小林煮好一锅饭了,那么必然要合理的分配好每个小朋友要吃的饭咯。

long size=fileSize/threadNum;//每个线程下载的部分
//startPos:起始位置   endPos:结束位置
for(int i=0;i<threadNum;i++)
{
    long startPos= i* size;
    long endPos;
    if(i==threadNum-1){
        endPos=0;
    }else{
        endPos=startPos+size;
    }
    if(startPos!=0){
        startPos++;
    }
    System.out.println("第"+(i+1)+"个线程下载的区间为:"+startPos+"----"+endPos);
}

2.3创建线程进行下载任务

哥们,饭已经给你分完了,那接下来就是吃光这包分配的饭勒。

//每循环一次就启动一个线程
DownloadThread downloadThread=new DownloadThread(startPos,endPos,url,i+1,address,threadNum,countDownLatch);
downloadThread.start();
class DownloadThread extends Thread{
    long startPos;
    long endPos;
    URL url;
    int index;
    String address;
    int threadNum;
    CountDownLatch countDownLatch;
    //创建构造函数传递参数进来,(需要哪些参数就传哪些过来)
    public DownloadThread(long startPos,long endPos,URL url,int index,String address,int threadNum,CountDownLatch countDownLatch)
    {
        this.startPos=startPos;
        this.endPos=endPos;
        this.url=url;
        this.index=index;
        this.address=address;
        this.threadNum=threadNum;
        this.countDownLatch=countDownLatch;
    }
    public void run(){

    }
}

2.4在线程内进行读写操作实现文件下载

虽然说饭已经吃下去了,但是哥们得消化呀,光吃不拉早晚得成小胖呀,那么接下来我们就需要进行文件下载咯,先读后写,先读后写,先读后写--IO流秘诀可不能忘。

//文件下载--先读后写
try {
    //这里用于断点续传,每次只请求文件的一部分
    URLConnection urlConnection = (HttpURLConnection) url.openConnection();
    if(index!=threadNum){
        urlConnection.setRequestProperty("Range","byte="+startPos+"-"+endPos);
    }else{
        urlConnection.setRequestPro
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值