客户端多线程下载

//这是主类

package pxy.s2.mutithead;
import java.net.;
import java.io.
;
public class MutiThread {

/****
 * 多线程的下载
 * 在客服端采用多条线程进行下载
 * 效率会高很多
 * 多线程的关键步骤有:
 * 首先读取网络资料的大小:根据其大小也在本地创建一个一样大小的文件
 * A:计算每个线程的下载开始和结束点:比如:假如我们客服端开启5个线程进行
 * 下载:则每个线程的负责的段有:资源的长度/线程数=每个线程的负责下载的段
 * 假设这里有5个线程id,从0--4--依次开始负责下载自己的段
 * 则有: int start=i*block;
 * int end=(i+1)*block -1;
 * 所以各个线程只负责其下载--不关联其他的线程
 * 
 */
public static void main(String[] args) throws Exception{
    //要下载的网络资料路径
    String path="http://127.0.0.1:8080/json/StarUML.rar";
    MutiThread.load(path,9);
}

private static void load(String path,int t) throws Exception{

    URL url = new URL(path);
    HttpURLConnection con=(HttpURLConnection)url.openConnection();
    con.setRequestMethod("GET");//设置请求的方法
    con.setReadTimeout(5000);//设置链接的时间
    int len=con.getContentLength();//获取网络资源的长度
    File file = new File(MutiThread.getContentName(path));//创建一个本地文件,并和网络资源文件的大小一样
    RandomAccessFile af = new RandomAccessFile(file, "rwd");
    af.setLength(len);//设置本地文件的大小和网络资源一样大
    int block=(len%t)==0?len/t:len/t+1;//获取每个线程负责的下载的区域
    /***
     * 以下是开启线程进行下载任务
     * 根据传来的线程数T进行开启
     */
    for(int i=0;i<t;i++){

        new DownLoad(i,file,url,block).start();
    }


}

private static String getContentName(String path) {

    return path.substring(path.lastIndexOf("/")+1);
}

}

//以下是子类
package pxy.s2.mutithead;

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

public class DownLoad extends Thread{

private int i;//标识一个线程的ID
private File file;//本地文件
private URL url;//负责链接的URL
private int block;//每个线程下载的块的大小

public DownLoad(int i, File file, URL url, int block) {
    this.i=i;
    this.file=file;
    this.url=url;
    this.block=block;
}

public void run(){

    /***
     * 开始进行下载的处理
     */

    int start=i*block;
    int end=(i+1)*block-1;
    try {
        HttpURLConnection con = (HttpURLConnection)url.openConnection();
        con.setReadTimeout(5000);
        con.setRequestMethod("GET");
        con.setRequestProperty("Range", "bytes="+start+"-"+end);//设置头字段--根据其下载的区域设置
        //创建一个随机file
        RandomAccessFile af = new RandomAccessFile(file,"rwd");
        af.seek(start);//在这里写入数据
        if(con.getResponseCode() == 206){//多线程下载的返回状态码为:206--不是200
            InputStream in = con.getInputStream();
            byte buf[] = new byte[1024];
            int len=0;
            while((len=in.read(buf))!=-1){
                af.write(buf,0,len);
            }
            af.close();
            in.close();
            System.out.println("第"+i+"线程下载完成");
        }else{
            System.out.println("第"+i+"线程没有完成下载");
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

}

你可能感兴趣的:(客户端多线程下载)