• JAVA下实现多线程断点下载


    多线程断点下载:顾名思义是用多线程实现的,断点是当第三方因素(断电、断网等)中断下载时,下次下载可以继续上次下载的地方下载。

    1、通过getContentLength可以获取要下载文件的大小,这样可以在本机上创建一个相同大小的文件用来下载。

    int fileLength = connection.getContentLength();

    2、由于是多线程,所以要给每一个线程均分分配要下载的位置。

    for(int i = 0; i < threadCount; i ++) {
        int startThread = i * blockSize;
        int endThread = (i + 1) * blockSize - 1;
        if( i == blockSize - 1) endThread = fileLength -1;
        new DownloadThread(i, startThread, endThread).start();
                        
    }

    3、启动每个线程下载时,请求头需要Range参数,值是bytes:xxx-xxx某事。比如"Range:0-10100",代表要下载的位置是从0到10100。

    connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);

    4、然后每次用RandomAccessFile写入数据到本机文件里。

    while((length = inputStream.read(buffer)) != -1) {
        randomAccessFile.write(buffer, 0, length);
    }

    5、当然每次下载时需要记录本线程下载了多少,以便断点时,下载的时候可以从下次下载的地方下载。

    total += length;
    int currentThreadPostion = startThred + total;
    RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
    randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
    randomAccessFile2.close();

    继承Thread类的DownloadThread类代码:

     1 public static class DownloadThread extends Thread {
     2         private int threadId;
     3         private int endThread;
     4         private int startThred;
     5         public DownloadThread(int threadId, int startThred, int endThread) {
     6             this.threadId = threadId;
     7             this.startThred = startThred;
     8             this.endThread = endThread;
     9         }
    10         public void run() {
    11             //分段请求网络连接,分段保存在本地
    12             synchronized (DownloadThread.class) {
    13                 currentRunThreadCount += 1;
    14             }
    15             try {
    16                 System.err.println("理论线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);
    17                 URL url = new URL(path);
    18                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    19                 connection.setRequestMethod("GET");
    20                 connection.setConnectTimeout(10 * 1000);
    21                 File file = new File(threadId+".txt");
    22                 if(file.exists()) {    //是否断点
    23                     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    24                     String lastPostion_str = bufferedReader.readLine();
    25                     startThred = Integer.parseInt(lastPostion_str);
    26                     bufferedReader.close();
    27                 }
    28                 //设置分段下载的头信息  Range:做分段
    29                 connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);
    30                 int code = connection.getResponseCode();
    31                 System.out.println(code);
    32                 if(code == 200) {    //200:请求全部资源成功  206:代表部分资源请求成功
    33                     InputStream inputStream = connection.getInputStream();
    34                     System.out.println(getFileName(path));
    35                     RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
    36                     randomAccessFile.seek(startThred);
    37                     byte[] buffer = new byte[1024*10];
    38                     int length = -1;
    39                     int total = 0;//记录下载的总量
    40                     System.err.println("实际线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);
    41                     while((length = inputStream.read(buffer)) != -1) {
    42                         randomAccessFile.write(buffer, 0, length);
    43                         total += length;
    44                         int currentThreadPostion = startThred + total;
    45                         RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
    46                         randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
    47                         randomAccessFile2.close();
    48                     }
    49                     randomAccessFile.close();
    50                     inputStream.close();
    51                     System.err.println("线程:"+threadId+"下载完毕");
    52                     synchronized (DownloadThread.class) {
    53                         currentRunThreadCount -= 1;
    54                         if(currentRunThreadCount == 0){
    55                             for(int i = 0; i < threadCount; i ++) {
    56                                 File file2 = new File(i+".txt");
    57                                 file2.delete();
    58                             }
    59                         }
    60                     }
    61                 }
    62                 
    63             } catch (Exception e) {
    64                 e.printStackTrace();
    65             }
    66             
    67              
    68             super.run();
    69         }
    70     }
    View Code

    完整代码:

      1 import java.io.BufferedReader;
      2 import java.io.File;
      3 import java.io.FileInputStream;
      4 import java.io.InputStream;
      5 import java.io.InputStreamReader;
      6 import java.io.RandomAccessFile;
      7 import java.net.HttpURLConnection;
      8 import java.net.URL;
      9 
     10 
     11 public class exp6 {
     12 
     13     /**
     14      * @param args
     15      */
     16     private static int threadCount = 3;
     17     private static int blockSize;
     18     private static String path = "http://starry97.cn/a.txt";
     19     private static int currentRunThreadCount = 0;
     20     public static void main(String[] args) {
     21         
     22         try {
     23             URL url = new URL(path);
     24             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
     25             connection.setRequestMethod("GET");
     26             connection.setConnectTimeout(10 * 1000);
     27             int code = connection.getResponseCode();
     28             if(code == 200) {
     29                 int fileLength = connection.getContentLength();
     30                 RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
     31                 randomAccessFile.setLength(fileLength);
     32                 blockSize = fileLength / threadCount;
     33                 for(int i = 0; i < threadCount; i ++) {
     34                     int startThread = i * blockSize;
     35                     int endThread = (i + 1) * blockSize - 1;
     36                     if( i == blockSize - 1) endThread = fileLength -1;
     37                     new DownloadThread(i, startThread, endThread).start();
     38                     
     39                 }
     40             }
     41         } catch (Exception e) {
     42             e.printStackTrace();
     43         }
     44         
     45     }
     46     
     47     
     48     public static class DownloadThread extends Thread {
     49         private int threadId;
     50         private int endThread;
     51         private int startThred;
     52         public DownloadThread(int threadId, int startThred, int endThread) {
     53             this.threadId = threadId;
     54             this.startThred = startThred;
     55             this.endThread = endThread;
     56         }
     57         public void run() {    
     58             synchronized (DownloadThread.class) {
     59                 currentRunThreadCount += 1;
     60             }
     61             //分段请求网络连接,分段保存在本地
     62             try {
     63                 System.err.println("理论线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);
     64                 URL url = new URL(path);
     65                 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
     66                 connection.setRequestMethod("GET");
     67                 connection.setConnectTimeout(10 * 1000);
     68                 File file = new File(threadId+".txt");
     69                 if(file.exists()) {    //是否断点
     70                     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
     71                     String lastPostion_str = bufferedReader.readLine();
     72                     startThred = Integer.parseInt(lastPostion_str);
     73                     bufferedReader.close();
     74                 }
     75                 //设置分段下载的头信息  Range:做分段
     76                 connection.setRequestProperty("Range", "bytes:"+startThred+"-" + endThread);
     77                 int code = connection.getResponseCode();
     78                 System.out.println(code);
     79                 if(code == 200) {    //200:请求全部资源成功  206:代表部分资源请求成功
     80                     InputStream inputStream = connection.getInputStream();
     81                     System.out.println(getFileName(path));
     82                     RandomAccessFile randomAccessFile = new RandomAccessFile(new File(getFileName(path)), "rw");
     83                     randomAccessFile.seek(startThred);
     84                     byte[] buffer = new byte[1024*10];
     85                     int length = -1;
     86                     int total = 0;//记录下载的总量
     87                     System.err.println("实际线程:"+threadId+",开始位置:"+startThred+",结束位置:"+endThread);
     88                     while((length = inputStream.read(buffer)) != -1) {
     89                         randomAccessFile.write(buffer, 0, length);
     90                         total += length;
     91                         int currentThreadPostion = startThred + total;
     92                         RandomAccessFile randomAccessFile2 = new RandomAccessFile(file, "rwd");
     93                         randomAccessFile2.write(String.valueOf(currentThreadPostion).getBytes());
     94                         randomAccessFile2.close();
     95                     }
     96                     randomAccessFile.close();
     97                     inputStream.close();
     98                     System.err.println("线程:"+threadId+"下载完毕");
     99                     synchronized (DownloadThread.class) {
    100                         currentRunThreadCount -= 1;
    101                         if(currentRunThreadCount == 0){
    102                             for(int i = 0; i < threadCount; i ++) {
    103                                 File file2 = new File(i+".txt");
    104                                 file2.delete();
    105                             }
    106                         }
    107                     }
    108                 }
    109                 
    110             } catch (Exception e) {
    111                 e.printStackTrace();
    112             }
    113             
    114              
    115             super.run();
    116         }
    117     }
    118     
    119     public static String getFileName(String path) {
    120         return path.substring(path.lastIndexOf("/")+1);
    121     }
    122 
    123 }
    View Code
  • 相关阅读:
    计算机学院大学生程序设计竞赛(2015’12)Study Words
    离散化
    一键拨打
    python中Strip()函数的用法
    笨方法学python 22,前期知识点总结
    笨方法学python之读写文件、open函数的用法
    Linux 多线程串口通信
    RSA加密前言
    GrabCut--Opencv篇
    队列
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7401771.html
Copyright © 2020-2023  润新知