• 多线程下载和断点续传技术的实现原理。


    package com.zzw.constant;
    
    public class Contant 
    {
        public static int threadCount = 3;
    }
    
    
      1 package com.zzw.download;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileInputStream;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.io.InputStream;
      9 import java.io.InputStreamReader;
     10 import java.io.RandomAccessFile;
     11 import java.net.HttpURLConnection;
     12 import java.net.MalformedURLException;
     13 import java.net.URL;
     14 import java.net.URLConnection;
     15 
     16 import javax.tools.FileObject;
     17 
     18 import com.zzw.constant.Contant;
     19 
     20 public class TestDownload 
     21 {
     22     //public static int threadCount = 3;
     23     public static int blockSize = 0;
     24 
     25     public static void main(String[] args) throws Exception 
     26     {
     27         URL url = new URL("http://localhost:8080/download/cc.zip");
     28         
     29         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     30         conn.setRequestMethod("GET");
     31         conn.setReadTimeout(10000);
     32         
     33         long length = conn.getContentLength();
     34         
     35         conn.connect(); //连接
     36         File file = new File("cc.zip");
     37         
     38         RandomAccessFile randomFile = new RandomAccessFile(file,"rwd");
     39         randomFile.setLength(length);
     40         
     41         //每一个线程他需要下载的大小
     42         System.out.println("总大小:" + length);
     43         blockSize = (int) (length / Contant.threadCount);
     44         System.out.println("每一个线程下载的大小:" + blockSize);
     45         long start = 1;
     46         long end = 0;
     47         for(int i=1; i < (Contant.threadCount+1); i++)
     48         {
     49             
     50             //1 >> 0 - 46354938 123456
     51             //2 >> 46354939 -(46354939 + 46354938)
     52             //3 >> 
     53             start = blockSize * (i -1);
     54             end = blockSize*i -1;
     55             if(i == Contant.threadCount)
     56             {
     57                 end = length;
     58             }
     59             System.out.println("" + i + "个线程下载的区间:" + start + " - " + end);
     60             new downloadThread(file, i, start, end).start();
     61         }
     62         
     63         conn.disconnect();
     64     }
     65 }
     66 
     67 class downloadThread extends Thread
     68 {
     69     private File path; //本地磁盘的地址
     70     private String url = "http://localhost:8080/download/cc.zip" ; //HTTP请求的地址
     71     private Integer threadID; //当前是第几个线程
     72     private long start; //该线程下载的起始位置
     73     private long end; //该线程的结束位置
     74     
     75     public downloadThread(File path, Integer threadID, long start,
     76             long end) {
     77         this.path = path;
     78         this.threadID = threadID;
     79         this.start = start;
     80         this.end = end;
     81         
     82     }
     83 
     84     @Override
     85     public void run() 
     86     {
     87         try {
     88             System.out.println(threadID + "开启读取");
     89             File contextFile = new File(threadID +".txt");
     90             if(!contextFile.exists())
     91             {
     92                 contextFile.createNewFile();
     93             }
     94             
     95             //读取断线信息里面的数据来重新的指定从哪里开始写
     96             BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(contextFile)));
     97             String info = reader.readLine();
     98             if(null != info && info.length() > 0)
     99             {
    100                 start = start + Integer.parseInt(info);
    101             }
    102             
    103             System.out.println("start........=" + start);
    104             URL uri = new URL(url);
    105             HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
    106             conn.setRequestProperty("Range", "bytes="+start +"-" + end);
    107             conn.setReadTimeout(50000);
    108             conn.setConnectTimeout(50000);
    109             
    110             conn.connect();
    111             
    112             //让http请求只请求一个片段
    113             System.out.println("bytes="+start +"-" + end);
    114             
    115             //判断一下是否为200?
    116             int status = conn.getResponseCode();
    117             
    118             if(status / 100 == 2)
    119             {
    120                 int total = 0; //总共下载的字节数
    121                 //FileOutputStream out = new FileOutputStream(new File(threadID +".txt")); 不靠谱了
    122                 RandomAccessFile random = new RandomAccessFile(path, "rw");
    123                 
    124                 random.seek(start);
    125                 InputStream in = conn.getInputStream();
    126                 byte[] buffer = new byte[1024];
    127                 int len = 0;
    128                 
    129                 while((len = in.read(buffer)) != -1)
    130                 {
    131                     RandomAccessFile duandian = new RandomAccessFile(contextFile, "rwd");
    132                     random.write(buffer, 0, len);
    133                     total += len;
    134                     duandian.write(String.valueOf(total).getBytes());
    135                     duandian.close();
    136                 }
    137                 in.close();
    138                 random.close();
    139             }
    140             conn.disconnect();
    141             System.out.println(threadID + "读取完成");
    142         } catch (MalformedURLException e) {
    143             e.printStackTrace();
    144         } catch (IOException e) {
    145             e.printStackTrace();
    146         }finally
    147         {
    148             synchronized (TestDownload.class)
    149             {
    150                 Contant.threadCount --;
    151                 System.out.println("Contant.threadCount = " + Contant.threadCount);
    152                 if(Contant.threadCount == 0)
    153                 {
    154                     for(int i=1; i < 4; i++)
    155                     {
    156                         File contextFile = new File(i +".txt");
    157                         System.out.println(contextFile.delete() +"   ccc");
    158                     }
    159                 }
    160             }
    161         }
    162         
    163     }
    164 }
  • 相关阅读:
    Rocky Linux8国内镜像源
    强制缓存和协商缓存的区别
    从源码来看VUE的执行流程
    plugin
    判断数据类型的方法
    获取函数参数
    BFC
    VUE的$nextTick
    HTTP
    JavaScript创建和触发自定义事件
  • 原文地址:https://www.cnblogs.com/labixiaoxin/p/4933779.html
Copyright © 2020-2023  润新知