首页 > 代码库 > 多线程下载(转)

多线程下载(转)

原文是在52上下载的。

感觉我们对IO和URL这些不够熟悉.很简单的.之前自己尝试过,感觉复杂化了,但也不好说.其实最想要的还是类似idm这种多线程,呵呵.

代码:

package com.test_four;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class Demo {
    public static int threadCount = 3;
    public static void main(String[] args) throws Exception {
//   1.连接服务器,获取一个文件,获取一个文件,获取文件的长度,在本地创建一个大小和服务器文件一样大的临时文件
        String path = "https://admdownload.adobe.com/bin/livebeta/flashplayer24_va_install.exe";
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        int code = conn.getResponseCode();
        if (code == 200) {
            //服务器返回的数据的长度 实际上就是文件的长度
            int length = conn.getContentLength();
            System.out.println("文件总长度:" + length);
//            在客户端本地创建出来一个大小跟服务器端文件一样的临时文件
            RandomAccessFile raf = new RandomAccessFile("xxx.exe", "rw");
//          指定创建的这个文件的长度
            raf.setLength(length);
            raf.close();
//           假设是三个线程去下载资源
//       平均每一个线程下载的文件的大小
            int blockSize = length/threadCount;
            for(int threadId = 1;threadId<=threadCount;threadId++){
//                第一个线程下载的开始位置
                int startIndex = (threadId -1)*blockSize;
                int endIndex = threadId*blockSize -1;
                if (threadId == threadCount) {//最后一个线程下载的长度要稍微长一点
                    endIndex = length;
                }
                System.out.println("线程:"+ threadId +"下载:---"+ startIndex +"--->"+ endIndex);
                new DownloadThread(path, threadId, startIndex, endIndex).start();
            }
        } else {
            System.out.println("服务器错误");
        }

    }
    public static class DownloadThread extends Thread{
        private int threadId;
        private int startIndex;
        private int endIndex;
        private String path;
        @Override
        public void run() {
            try {
                URL url = new URL(path);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(5000);
                connection.setRequestMethod("GET");
//                重要:请求服务器下载部分的文件指定文件的位置
                connection.setRequestProperty("Range","bytes=" + startIndex +"-" +endIndex);
                int code = connection.getResponseCode();//从服务器请求全部资源200 ok   如果从服务器请求部分资源206 ok
//                System.out.println("code:" + code);
                InputStream is =connection.getInputStream();//已经设置了请求的位置,返回的是当前位置对应的文件的输入流
                RandomAccessFile raf = new RandomAccessFile("xxx.exe", "rw");
                raf.seek(startIndex);//随机写文件的时候从哪个位置开始写

                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = is.read(buffer))!=-1) {
                    raf.write(buffer, 0, len);
                }
                is.close();
                raf.close();
                System.out.println("线程:"+threadId +"下载完毕");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /*
         * threadId 线程id
         * startIndex 线程下载的开始位置
         * endIndex 线程下载的结束位置
         * path 下载文件在服务器的路径
         */
        public DownloadThread(String path,int threadId, int startIndex, int endIndex) {
            super();
            this.threadId = threadId;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.path = path;
        }
    }

}

 

多线程下载(转)