Java 多线程下载

来源:互联网 发布:拍照软件大全 编辑:程序博客网 时间:2024/05/21 06:43

测试类:

public class download_test {    /**     * @param args     *///    思路:////            1、基本思路是将文件分段切割、分段传输、分段保存。////            2、分段切割用到HttpUrlConnection对象的setRequestProperty("Range", "bytes=" + start + "-" + end)方法。////            3、分段传输用到HttpUrlConnection对象的getInputStream()方法。////            4、分段保存用到RandomAccessFile的seek(int start)方法。////            5、创建指定长度的线程池,循环创建线程,执行下载操作。    public static void main(String[] args) throws IOException {        String urlLocation = "http://pic17.nipic.com/20111102/3707281_235344313129_2.jpg";        String filename=DownloadFileWithThreadPool.getUrl_filename(urlLocation);        String filePath="./"+filename;        int poolLength=3;        try {            DownloadFileWithThreadPool manager = new DownloadFileWithThreadPool();            manager.getFileWithThreadPool(urlLocation,filePath,poolLength);            System.out.println("success");        } catch (IOException e) {            e.printStackTrace();        }    }}

-

创建 线程池
执行:threadpool.execute(target)

public class DownloadFileWithThreadPool {    public void getFileWithThreadPool(String urlLocation, String filePath, int poolLength) throws IOException {        // Executor线程池        Executor threadPool = Executors.newFixedThreadPool(poolLength);        long len = getContentLength(urlLocation);        for (int i = 0; i < poolLength; i++) {            long start = i * len / poolLength;            long end = (i + 1) * len / poolLength - 1;            if (i == poolLength - 1) {                end = len;            }            //DownloadWithRange实现runnable接口类,重写run函数            DownloadWithRange download = new DownloadWithRange(urlLocation, filePath, start, end);            threadPool.execute(download);   //Executor.execute(Runnalbe)        }    }    public static long getContentLength(String urlLocation) throws IOException {        URL url = null;        if (urlLocation != null) {            url = new URL(urlLocation);        }        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setReadTimeout(5000);        conn.setRequestMethod("GET");        long len = conn.getContentLength();    //单位byte     //   System.out.println("文件大小:" + len + " bytes");        return len;    }    public static String getUrl_filename(String urlLocation) throws IOException {        URL url = null;        if (urlLocation != null) {            url = new URL(urlLocation);        }        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        URL absUrl = conn.getURL();// 获得真实Url //       System.out.println(absUrl.toString());        // 打印输出服务器Header信息//        Map<String, List<String>> map = conn.getHeaderFields();//        for (String str : map.keySet()) {//             System.out.println(str + "   " + map.get(str));//        }        String suffixes="avi|mpeg|3gp|mp3|mp4|wav|jpeg|gif|jpg|png|apk|exe|pdf|rar|zip|docx|doc";        Pattern pat= Pattern.compile("[\\w]+[\\.]("+suffixes+")");        Matcher mc=pat.matcher(absUrl.toString());        String substring="";        while(mc.find()){            substring = mc.group();            //System.out.println("filename:"+ substring);        }        return substring;    }}

执行分割文件以及保存类
1.分段切割用到HttpUrlConnection对象的setRequestProperty(“Range”, “bytes=” + start + “-” + end)
2.分段传输用到HttpUrlConnection对象的getInputStream()方法
将已经切割好的conn对象的数据下载下来
3.RandomAccessFile seek(start)方法将每一段数据保存下来

public class DownloadWithRange implements Runnable{    private String urlLocation;    //由url获取HttpURLConnection类型    private String filePath;    private long start;    private long end;    DownloadWithRange(String urlLocation, String filePath, long start, long end)    {        this.urlLocation = urlLocation;        this.filePath = filePath;        this.start = start;        this.end = end;    }    @Override    public void run()    {        try        {            HttpURLConnection conn = getHttp();            conn.setRequestProperty("Range", "bytes=" + start + "-" + end);   //setRequestProperty函数进行文件切割            File file = new File(filePath);            RandomAccessFile out = null;            if (file != null)            {                //对于待生成文件——file创建随机存取文件流                out = new RandomAccessFile(file, "rwd");            }            out.seek(start);  //从start位置开始写入——seek函数            InputStream in = conn.getInputStream();     //getInputStream分段传输。这里的HttpURLConnection已经是分割后的内容了            byte[] b = new byte[1024];            int len = 0;            while ((len = in.read(b)) != -1)    //inputstream read 方法取出数据流中的数据  ————read(),read(byte[] b),read(byte[] b, int off, int len)            {                out.write(b, 0, len);    //把b内容写入out            }            in.close();            out.close();        }        catch (Exception e)        {            e.getMessage();        }    }    public HttpURLConnection getHttp() throws IOException    {        URL url = null;        if (urlLocation != null)        {            url = new URL(urlLocation);        }        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setReadTimeout(5000);        conn.setRequestMethod("GET");        return conn;    }}
0 0
原创粉丝点击