Android菜鸟之路-多线程下载

Android客户端下载步骤

  1. 在Android客户端首先创建一个空文件(空白文件),大小跟服务器的一模一样。
  2. 开启若干线程,分别去下载服务器上对应的资源。
  3. 如果所有的线程都下载完毕,服务器的资源就下载完毕。

Android客户端下载逻辑

  1. 获取到服务器端资源文件的大小(connection.getContentLength())

    String path = "http://localhost:8080/ff.exe";
    
    URL url = new URL(path);
    
    // 获取链接
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    
    // 参数
    connection.setRequestMethod("GET");
    connection.setConnectTimeout(5000);
    
    // 响应码
    int responseCode = connection.getResponseCode();
    
    if (responseCode == 200) {
    
        // 得到服务端返回的文件大小
        long contentLength = connection.getContentLength();
        System.out.println("服务器文件大小:"+contentLength);
    }
    
    // 断开连接
    connection.disconnect();
    
  2. 在本地创建一个大小和服务器一样的的空白文件

    File file = new File("temp.ext");
    RandomAccessFile raf= new RandomAccessFile(file, "rw");
    raf.setLength(contentLength);
    
  3. 根据开启线程的数量,把服务器资源给等分成若干份(threadCount:线程数量)

    假设文件大小是10个byte。(长度:length)
    假设3个线程(线程数量:threadCount)。
     int blockSize = length / threadCount;
    线程1 下载3个byte    1-3     0 * blockSize + 1 ~ 1 * blockSize
    线程2 下载3个byte    4-6     1 * blockSize + 1 ~ 2 * blockSize 
    线程3 下载4个byte    7-10    2 * blockSize + 1 ~ 3 * blockSize(length)
    
    // 开启若干个子线程,分别去下载对应的资源
    long threadCount = 3;
    long blockSize = contentLength / threadCount;
    
    for (int i = 1; i <= threadCount; i++) {
        // 计算下载起始、结束位置
        long startIndex = (i - 1) * blockSize + 0;// 服务器也是从0开始
        long endIndex = i * blockSize - 1; //
        // 最后一个线程
        if (i == threadCount) {
            endIndex = contentLength - 1;
        }
        System.out.println("开启线程:" + i + ",下载的位置:(" + startIndex + "~"
                + endIndex + ")");
        new DownloadThread(i, startIndex, endIndex, path).start();
    }
    
  4. 创建线程类

    static class DownloadThread extends Thread {
        private int threadId;
        private long startIndex;
        private long endIndex;
        private String path;
    
        public DownloadThread(int threadId, long startIndex, long endIndex,
                String path) {
            super();
            this.threadId = threadId;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.path = path;
        }
    
        public void run() {
            URL url;
            try {
                url = new URL(path);
    
                // 获取链接
                HttpURLConnection connection = (HttpURLConnection) url
                        .openConnection();
    
                // 参数
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(5000);
                // 告诉服务器下载的参数
                connection.setRequestProperty("Range", "bytes=" + startIndex
                        + "-" + endIndex);
    
                // 响应码
                int responseCode = connection.getResponseCode();
    
                System.out.println("服务器状态码:" + responseCode);
                // 下载服务器文件,返回的是206
                if (responseCode == 206) {
                    InputStream inputStream = connection.getInputStream();
    
                    File file = new File("temp.exe");
                    RandomAccessFile raf = new RandomAccessFile(file, "rw");
                    // 指定文件开始写的位置
                    raf.seek(startIndex);
                    System.out.println("第" + threadId + "个线程,写文件的开始、结束位置("
                            + (startIndex) + "," + (endIndex) + ")");
    
                    int len = 0; 
                    byte[] buf = new byte[1024];
                    while ((len = inputStream.read(buf)) != -1) {
                        raf.write(buf, 0, len);
                    }
    
                    inputStream.close();
                    raf.close();
                    System.out.println("第" + threadId + "个线程下载完毕了");
    
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。