Android使用多线程实现断点下载

2019-12-10 18:32:23于丽

  这样只是实现了通过连接服务器来获取文件的长度..然后去设置每一个线程下载的开始位置和结束位置..这里只是完成了这些步骤..有了下载的开始位置和结束位置..我们就需要开启线程来完成下载了...因此我们需要自己定义下载的过程...

  首先我们需要明确思路:既然是断点下载..那么如果一旦发生了断点情况..我们在下一次进行下载的时候需要从原来断掉的位置进行下载..已经下载过的位置我们就不需要进行下载了..因此我们需要记载每一次的下载记录..那么有了记录之后..一旦文件下载完成之后..这些记录就需要被清除掉...因此明确了这两个地方的思路就很容易书写了..

 

//下载线程的定义..  
public static class DownLoadThread implements Runnable{

    private int threadID;
    private int startIndex;
    private int endIndex;
    private String path;
    
    public DownLoadThread(int threadID,int startIndex,int endIndex,String path){
      
      this.threadID = threadID;
      this.startIndex = startIndex;
      this.endIndex = endIndex;
      this.path = path;
      
    }
    
    @Override
    public void run() {
      // TODO Auto-generated method stub
      
      try {
        
        //判断上一次是否下载完毕..如果没有下载完毕需要继续进行下载..这个文件记录了上一次的下载位置..
        File tempfile =new File(threadID+".txt");
        if(tempfile.exists() && tempfile.length()>0){
          
          FileInputStream fis = new FileInputStream(tempfile);
          byte buffer[] = new byte[1024];
          int leng = fis.read(buffer);
          int downlength = Integer.parseInt(new String(buffer,0,leng));//从上次下载后的位置开始下载..重新拟定开始下载的位置..
          startIndex = downlength;
          fis.close();
        }
        
        URL url = new URL(path);
        HttpURLConnection conn =(HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(5000);
        conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
        
        int status = conn.getResponseCode();
        //206也表示服务器响应成功..
        if(status == 206){
          
          //获取服务器返回的I/O流..然后将数据写入文件当中..
          InputStream in = conn.getInputStream();
          
          //文件写入开始..用来保存当前需要下载的文件..
          RandomAccessFile raf = new RandomAccessFile("jdk.exe", "rwd");
          raf.seek(startIndex);
          
          
          int len = 0;
          byte buf[] =new byte[1024];
          
          //记录已经下载的长度..
          int total = 0;
          
          while((len = in.read(buf))!=-1){
            
            //用于记录当前下载的信息..
            RandomAccessFile file =new RandomAccessFile(threadID+".txt", "rwd");
            total += len;
            file.write((total+startIndex+"").getBytes());
            file.close();
            //将数据写入文件当中..
            raf.write(buf, 0, len);
            
          }
          in.close();
          raf.close();
          
          
        }  
        
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }finally{
        //如果所有的线程全部下载完毕后..也就是任务完成..清除掉所有原来的记录文件..
        runningThread -- ;
        if(runningThread==0){
          for(int i=1;i<threadCount;i++){
            File file = new File(i+".txt");
            file.delete();
          }
        }
      }
    }
  }