JDBC线程_下载文件

基本原理:
利用URLConnection获取要下载文件的长度、头部等相关信息,并设置响应的头部信息。并且通过URLConnection获取输入流,将文件分成指定的块,每一块单独开辟一个线程完成数据的读取、写入。通过输入流读取下载文件的信息,然后将读取的信息用RandomAccessFile随机写入到本地文件中。(同时,每个线程写入的数据都文件指针也就是写入数据的长度,需要保存在一个临时文件中。这样当本次下载没有完成的时候,下次下载的时候就从这个文件中读取上一次下载的文件长度,然后继续接着上一次的位置开始下载。并且将本次下载的长度写入到这个文件中。)

/**
*内部实现
*/
public class Download extends Thread{
    private int startIndex;//线程开始下载位置
    private int endIndex;//线程结束下载位置
    private int threadID;//线程编号

    public Download(int startIndex, int endIndex, int threadID) {
        this.startIndex = startIndex;
        this.endIndex = endIndex;
        this.threadID = threadID;
    }

    @Override
    public void run() {

        try {
            //URL统一资源管理器,可以直接打开网络地址
            URL url=new URL(DownloadTest.path);
            //因为基于http请求,获取HttpURLConnection,获取网络链接对象,就可以和服务器建立链接
            try {
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                //设置参数
                conn.setRequestMethod("GET");//get请求
                conn.setConnectTimeout(5000);//连接超时
                conn.setReadTimeout(5000);//读取超时
                conn.setRequestProperty("Range","bytes="+startIndex+"-"+endIndex);//设置范围请求参数,获取线程下载范围
                if(conn.getResponseCode()==206){//表示部分数据ok
                    //取出连接中的数据
                    InputStream is=conn.getInputStream();//存储的是服务器上面  百度客户端数据
                    //提供一个接收数据的地方(本地接收)
                    File file=new File("BaiduNetdisk_6.9.7.4.exe");
                    //输出流,开始写数据,使用随机读写流
                    RandomAccessFile raf=new RandomAccessFile(file,"rwd");
                    raf.seek(startIndex);//跳转到每个线程,开始读取的位置
                    System.out.println("线程:"+threadID+" 开始的位置:"+startIndex+"---"+" 结束位置"+endIndex);
                    int len=0;
                    byte[] buf=new byte[1024];
                    while ((len=is.read(buf))!=-1){
                        raf.write(buf,0,len);
                    }
                    System.out.println("线程:"+threadID+"下载完毕...");
                    raf.close();
                    DownloadTest.finishedThread++;
                    //如果所有线程都下载完毕 ,让finishedThread 为0
                    synchronized (DownloadTest.path){
                        DownloadTest.finishedThread=0;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}
/**
*多线程测试类
*/
public class DownloadTest {
    static String path = "http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe";
    static int threadCount = 3; //3个线程
    static int finishedThread = 0;  //和 线程数 有关  ,记录每一个线程是否执行完毕

    public static void main(String[] args) throws IOException {
        //统一资源管理器  ,可以直接打开 网络地址
        URL url  = new URL(DownloadTest.path);
        //因为基于http请求 , 获取HttpURLConnection   , 获取网络链接对象 ,就可以和服务器建立链接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置一些参数
        conn.setRequestMethod("GET");   //get请求
        conn.setConnectTimeout(5000);   //链接超时
        conn.setReadTimeout(5000);      //读取超时

        if(conn.getResponseCode()==200){
            //1.拿到文件总大小
            int contentLength=conn.getContentLength();
            //2.每个线程下载的大小
            int size=contentLength/threadCount;
            //3.开启线程执行下载
            for (int i = 0; i <threadCount ; i++) {
                int startIndex = i*size;        // (i从0开始 )
                int endIndex = (i+1)*size;     //结束位置
                Download thread = new Download(startIndex,endIndex,i);
                thread.start();
            }

        }
    }
}

执行结果:

线程:2 开始的位置:1067540--- 结束位置1601310
线程:1 开始的位置:533770--- 结束位置1067540
线程:0 开始的位置:0--- 结束位置533770
线程:0下载完毕...
线程:2下载完毕...
线程:1下载完毕...
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值