实现多线程下载

package com.zzw.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MultiThreadDownload {

    //规定下载服务器的资源用三条线程去下载
    private static int threadCount =3;
    private static String path="http://192.168.1.102:8080/file.txt";
    public static void main(String[] args) {
        //向服务器发送请求拿到要下载的文件的长度是多少
        try {
            URL url=new URL(path);
            HttpURLConnection connection=(HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            int code=connection.getResponseCode();
            if (code==200) {
                //拿到文件的长度大小
                int length=connection.getContentLength();

                File file=new File(getFileName(path));

                RandomAccessFile raf=new RandomAccessFile(file, "rw");
                raf.setLength(length);
                raf.close();

                //求出每一个线程下载的大小
                int blockSize=length/threadCount;

                //启动线程去下载文件
                for(int threadId=0;threadId<threadCount;threadId++){
                    int startIndex=threadId*blockSize;
                    int endIndex=(threadId+1)*blockSize-1;
                    if(threadId==(threadCount-1)){
                        endIndex=length-1;
                    }

                    new DownloadFilePartThread(threadId, startIndex, endIndex).start();

                }                               
            }           
        } catch (Exception e) {
            e.printStackTrace();
        }                   
    }
    private static class DownloadFilePartThread extends Thread{
        private int threadId;//线程的id号
        private int startIndex;//线程下载的开始位置
        private int endIndex;//线程下载的结束位置

        public  DownloadFilePartThread(int threadId, int startIndex,int endIndex) {

            this.threadId=threadId;
            this.startIndex=startIndex;
            this.endIndex=endIndex;
        }
        @Override
        public void run() {
            //去干下载  ----下载目标数据
            //需要连接服务器
            System.out.println("第"+threadId+"线程开始下载了:下载 从"+startIndex+"~"+endIndex);   
            try {
                URL url=new URL(path);
                HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(5000);
                //在多线程下载的时候,每条线程只需要目标文件的一部分数据
                //需要告诉服务器只需要那一段得数据
                //通过设置http的请求头可以实现,告诉服务器,只需要目标端的数据

                //startIndex-----endIndex
                connection.setRequestProperty("range", "bytes="+startIndex+"-"+endIndex);
                //获得服务器给返回的目标端的数据
                //返回的响应码是206(状态码)-----代表部分数据
                int code=connection.getResponseCode();
                if(code==206){
                    //拿到数据
                    InputStream in=connection.getInputStream();
                    //将得到的数据写入到文件中
                    File file=new File(getFileName(path));
                    RandomAccessFile raf=new RandomAccessFile(file, "rw");
                    //要告诉从哪个位置开始写
                    raf.seek(startIndex);

                    int len=0;
                    byte[] buf=new byte[1024];
                    while((len=in.read(buf))>0){
                        raf.write(buf,0,len);
                    }
                    in.close();
                    raf.close();                            

                }
                System.out.println("第"+threadId+"线程下载结束了"); 

            } catch (Exception e) {         
                e.printStackTrace();
            }


        }
    }   
    public static  String getFileName(String path){
        int index=path.lastIndexOf("/");
        return path.substring(index+1);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值