[javascript学习指南]java多线程实现文件下载功能

更新时间:2021-05-27    来源:Access    手机版     字体:

【www.bbyears.com--Access】

多线程下载文件的思路:

1.首先获取到文件的总大小
获取文件大小的方式是通过网络读取,getContentLength()即可获取到文件的大小,使用RandomAccessFile()支持随机访问

2.根据所准备的线程数据,计算每一个线程需要下载的文件的大小

上图显示下载400M的电影分4个线程下载,每一个线程分别下载各自数据段中的数据,第一个线程下载0-100M,第二个下载100M-200M之间的数据,依次类推。因此下载过程中需要记住的是的开始位置段和结束位置段,其实只需要开始位置就可以了,结束为止可以根据开始位置加上下载的大小来推断获取。

3.获取到大小数据以后,开始用线程循环读取每一个区间的数据
这个里面需要注意的是,要更新数据的写入位置seek(startIndex),逐段填满,不然会出现覆盖以前的数据。

 

 代码如下

packagecom.ldw.multilthreaddownload;

  

importjava.io.File;

importjava.io.InputStream;

importjava.io.RandomAccessFile;

importjava.net.HttpURLConnection;

importjava.net.URL;

  

publicclassMultidownload {

  

 staticintThreadCount =3;//线程的个数

 staticString path ="http://192.168.0.102:8080/QQ.exe"; //确定下载地址

 publicstaticvoidmain(String[] args) {

  // TODO Auto-generated method stub

    

  //发送get请求,请求这个地址的资源

  try{

   URL url =newURL(path);

   HttpURLConnection conn = (HttpURLConnection) url.openConnection();

   conn.setRequestMethod("GET");

   conn.setConnectTimeout(5000);

   conn.setReadTimeout(5000);

   if(conn.getResponseCode() ==200){

    //获取到请求资源文件的长度

    intlength = conn.getContentLength();

    File file =newFile("QQ.exe");

    //创建随机存储文件

    RandomAccessFile raf =newRandomAccessFile(file,"rwd");

    //设置临时文件的大小

    raf.setLength(length);

    //关闭raf

    raf.close();

    //计算出每一个线程下载多少字节

      

    intsize = length / Multidownload.ThreadCount;

      

    for(inti =0; i < Multidownload.ThreadCount; i ++){

     //startIndex,endIndex分别代表线程的开始和结束位置

     intstartIndex = i * size;

     intendIndex = (i +1) * size -1;

     if(i == ThreadCount -1){

      //如果是最后一个线程,那么结束位置写死

      endIndex = length -1;

     }

     System.out.println("线程"+ i +"的下载区间是"+ startIndex +"到"+ endIndex);

     newDownLoadThread(startIndex, endIndex, i).start();//创建线程下载数据

    }

   }

  }catch(Exception e) {

   // TODO Auto-generated catch block

   e.printStackTrace();

  }

  

 }

  

}

  

classDownLoadThreadextendsThread{

 intstartIndex;

 intendIndex;

 intthreadId;

   

 publicDownLoadThread(intstartIndex,intendIndex,intthreadId) {

  super();

  this.startIndex = startIndex;

  this.endIndex = endIndex;

  this.threadId = threadId;

 }

  

 @Override

 publicvoidrun(){

  //使用http请求下载安装包文件

  URL url;

  try{

   url =newURL(Multidownload.path);

   HttpURLConnection conn = (HttpURLConnection) url.openConnection();

   conn.setRequestMethod("GET");

   conn.setConnectTimeout(5000);

   conn.setReadTimeout(5000);

   //设置请求数据的区间

   conn.setRequestProperty("Range","bytes="+ startIndex +"-"+ endIndex);

   //请求部分数据的响应码是206

   if(conn.getResponseCode() ==206){

    //获取一部分数据来读取

    InputStream is = conn.getInputStream();

    byte[] b =newbyte[1024];

    intlen =0;

    inttotal =0;

    //拿到临时文件的引用

    File file =newFile("QQ.exe");

    RandomAccessFile raf =newRandomAccessFile(file,"rwd");

    //更新文件的写入位置,startIndex

    raf.seek(startIndex);

    while((len = is.read(b)) != -1){

     //每次读取流里面的数据,同步吧数据写入临时文件

     raf.write(b,0, len);

     total += len;

     System.out.println("线程"+ threadId +"下载了"+ total);

    }

    System.out.println("线程"+ threadId +"下载过程结束===========================");

    raf.close();

   }

  }catch(Exception e) {

   // TODO Auto-generated catch block

   e.printStackTrace();

  }

    

 };

}

 

本文来源:http://www.bbyears.com/shujuku/120129.html