• 多线程下载原理


         基本原理:利用HttpsURLConnection获取要下载文件的长度、头部等相关信息,并设置响应的头部信息。并且通过 HttpsURLConnection获取输入流,将文件分成指定的块,每一块单独开辟一个线程完成数据的读取、写入。通过输入流读取下载文件的信息,然 后将读取的信息用RandomAccessFile随机写入到本地文件中。同时,每个线程写入的数据都文件指针也就是写入数据的长度,需要保存在一个临时 文件中。这样当本次下载没有完成的时候,下次下载的时候就从这个文件中读取上一次下载的文件长度,然后继续接着上一次的位置开始下载。并且将本次下载的长 度写入到这个文件中。

     1 package com.gaolei.download;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 import java.io.RandomAccessFile;
     7 import java.net.URL;
     8 
     9 import javax.net.ssl.HttpsURLConnection;
    10 
    11 public class MulThreadDownload {
    12 
    13     public static void main(String[] args) throws Exception {
    14         String path = "http://192.168.0.1/videonews/QQWubiSetup.exe";
    15         new MulThreadDownload().download(path, 3);
    16     }
    17 
    18     /**
    19      * 下载文件
    20      *
    21      * @param path网络文件路径
    22      * @throws Exception
    23      */
    24     private void download(String path, int threadsize) throws Exception {
    25         URL url = new URL(path);
    26         HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    27         conn.setConnectTimeout(5000);
    28         conn.setRequestMethod("GET");
    29         if (conn.getResponseCode() == 200) {
    30             int length = conn.getContentLength(); // 获取网络文件的长度
    31             File file = new File(getFilename(path));
    32             RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");// 在本地生成一个长度相等的文件
    33             accessFile.setLength(length);
    34             accessFile.close();
    35 
    36             // 计算每条线程负责下载的数据量
    37             int block = length % threadsize == 0 ? length / threadsize : length
    38                     / threadsize + 1;
    39             for (int threadid = 0; threadid < threadsize; threadid++) {40                 new DownloadThread(threadid, block, url, file).start();41             }42         } else {43             System.out.println("下载失败!");44         }45 46     }47 48     private class DownloadThread extends Thread {49 50         private int threadid;51         private int block;52         private URL url;53         private File file;54 55         public DownloadThread(int threadid, int block, URL url, File file) {56             this.threadid = threadid;57             this.block = block;58             this.url = url;59             this.file = file;60         }61 62         @Override63         public void run() {64             int start = threadid * block; // 计算该线程从网络文件的什么位置开始下载65             int end = (threadid + 1) * block - 1; // 下载到网络文件的什么位置结束66 67             try {68                 RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");// 在本地生成一个长度相等的文件69                 accessFile.seek(start);70                 HttpsURLConnection conn = (HttpsURLConnection) url71                         .openConnection();72                 conn.setConnectTimeout(5000);73                 conn.setRequestMethod("GET");74                 conn.setRequestProperty("Range", "bytes=" + start + "-" + end);75                 if (conn.getResponseCode() == 206) {76                     InputStream inStream = conn.getInputStream();77                     byte[] buffer = new byte[1024];78                     int len = 0;79                     while ((len = inStream.read(buffer)) != -1) {80                         accessFile.write(buffer, 0, len);81                     }82                     accessFile.close();83                     inStream.close();84                 }85                 System.out.println("第" + (threadid + 1) + "条线程已经下载完成!");86             } catch (IOException e) {87                 e.printStackTrace();88             }89 90         }91 92     }93 94     private String getFilename(String path) {95         return path.substring(path.lastIndexOf("/") + 1);96     }97 }98

  • 相关阅读:
    ans_rproxy 说明
    ubuntu adduser
    linux 修改 elf 文件的dynamic linker 和 rpath
    What Is The Promiscuous Mode
    gpart 分区工具
    TortoiseSVN的基本使用方法
    svn和git的区别及适用场景
    TortoiseSVN 和 VisualSVN Server 使用教程
    SVN中trunk、branches、tag的使用
    C/C++中substr函数的应用(简单讲解)
  • 原文地址:https://www.cnblogs.com/xgjblog/p/4125966.html
Copyright © 2020-2023  润新知