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();
        }
    }
}