zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    select、poll和epoll
    Linux 常用命令之文件和目录
    SmartPlant Review 帮助文档机翻做培训手册
    SmartPlant Foundation 基础教程 3.4 菜单栏
    SmartPlant Foundation 基础教程 3.3 标题栏
    SmartPlant Foundation 基础教程 3.2 界面布局
    SmartPlant Foundation 基础教程 3.1 DTC登陆界面
    SmartPlant Foundation 基础教程 1.4 SPF架构
    SmartPlant Foundation 基础教程 1.3 SPF其他功能
    SmartPlant Foundation 基础教程 1.2 SPF集成设计功能
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7401771.html
Copyright © 2011-2022 走看看