zoukankan      html  css  js  c++  java
  • java多线程下载

    多线程下载是通过占有服务器资源来提高速度的。
    每个线程应该下载一个文件的不同位置,假如现在有一个长度为10的资源,有三个线程,那么第一个线程下载的长度为012,第二个为345,第四个为6789
    所以问题来了每个线程下载的长度是多少呢?
    线程的id为0,1,2
    每个线程下载的数量=总长度/线程数量
    size=10/3
    start:id*size
    end:(id+1)*size-1
    最后一个线程的结束位置为:总长度-1

    package down;
    
    
    import java.io.File;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class Down {
        
        static int threadCount = 3;
        static String path = "http://192.168.21.1:8080/ok/ideaIU-14.1.3.exe";
        
        /**
         * @param args
         */
        public static void main(String[] args) {
            try {
                URL url = new URL(path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(5000);
                if(conn.getResponseCode()==200){
                    //第一次请求要下载的长度
                    int length = conn.getContentLength();
                    //应该从字符串中截取文件名称
                    File file = new File("ideaIU-14.1.3.exe");
                    //在下载之前生成临时文件,占位置
                    RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
                    //给临时文件大小
                    rdm.setLength(length);
                    //关闭
                    rdm.close();
                    //计算每个线程应该下载的长度
                    int size = length/threadCount;
                    //为每个线程分配开始位置和结束位置
                    for (int i = 0; i <threadCount; i++) {
                        int start = i*size;
                        int end = (i+1)*size-1;
                        //最后一个线程的结束位置为总长度
                        if(i==threadCount-1){
                            end= length;
                        }
                        System.out.println(i+"线程下载区间"+start+"---"+end);
                        //每次都调用新的线程
                        new DownThread(start, end, i).start();
                    }
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    
    
    }
    //线程
    class DownThread extends Thread{
        private int start;
        private int end;
        private int threadId;
        
        public DownThread(int start, int end, int threadId) {
            this.start = start;
            this.end = end;
            this.threadId = threadId;
        }
    
        @Override
        public void run() {
            try {
                //再次请求网络
                URL url = new URL(Down.path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(5000);
                //设置本次请求的文件的长度
                conn.setRequestProperty("Range","bytes="+start+"-"+end);
                //请求部分数据是206
                if(conn.getResponseCode()==206){
                    //得到请求长度的文件输入流
                    InputStream is = conn.getInputStream();
                    byte[] b = new byte[1024];
                    int len = 0;
                    //记录每一次下载字节数
                    int totle =0;
                    //应该从字符串中截取文件名称
                    File file = new File("ideaIU-14.1.3.exe");
                    //拿到之前占位置那个文件,相当于输出流
                    RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
                    //改变写入文件的开始位置
                    rdm.seek(start);
                    while((len=is.read(b))!=-1){
                        //每次读取流里的数据写到临时文件里
                        rdm.write(b, 0, len);
                        totle += len;
                        System.out.println(threadId+"线程"+"下载了"+totle);
                    }
                    rdm.close();
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    docker 镜像管理
    docker 常用操作
    docker 简单介绍与安装
    emacs 缩进
    stl标准库 iterator_traits
    emacs semantic,speedbar,gdb汇总
    在emacs 里使用gdb
    emacs speedbar功能介绍
    前端基础之BOM和DOM
    modules模块
  • 原文地址:https://www.cnblogs.com/84126858jmz/p/4954827.html
Copyright © 2011-2022 走看看