smanzheng 发表于 2015-07-01 09:57

多线程下载

多个线程同时下载网络文件,基于http协议
代码package com.test.download;

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

/*
* 多线程下载
*/
public class MulThreadDownload {

    public static void main(String[] args) throws Exception {
      String path = "http://pic.4j4j.cn/upload/pic/20130909/681ebf9d64.jpg";
      new MulThreadDownload().download(path,3);
    }
   
    public void download (String path,int threadsize) throws Exception{
      URL url = new URL(path);
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setConnectTimeout(5000);
      conn.setRequestMethod("GET");
      if(conn.getResponseCode() == 200){
            //获取网络文件长度
            int length = conn.getContentLength();   
            //新建本地文件保存下载数据
            File file = new File(getFilename(path));
            //计算每条线程负责下载的数据量
            int block = length%threadsize==0 ? length/threadsize : length/threadsize+1;
            //开启指定数目的线程同时下载
            for(int threadid = 0; threadid < threadsize; threadid++){
                new DownloadThread(threadid,block,url,file).start();
            }
      }else{
            System.out.println("下载失败!");
      }
    }
   
    private class DownloadThread extends Thread{
      private int threadid;   //线程编号
      private int block;      //下载块大小
      private URL url;      //下载链接
      private File file;      //下载数据保存文件
      public DownloadThread(int threadid, int block, URL url, File file) {
            this.threadid = threadid;
            this.block = block;
            this.url = url;
            this.file = file;
      }

      public void run() {
            int start = threadid * block;       //本线程下载数据写入文件开始位置
            int end = (threadid+1) * block - 1; //本线程下载数据写入文件结束位置
            try {
                //创建一个随机访问文件流对象
                RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
                //文件指针偏移至正确写入位置
                accessFile.seek(start);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5000);
                conn.setRequestMethod("GET");
                //设置请求数据的范围
                conn.setRequestProperty("Range", "bytes="+start+"-"+end);
                if(conn.getResponseCode() == 206){//状态码206:(部分内容) 服务器成功处理了部分 GET 请求
                  InputStream inStream = conn.getInputStream();
                  byte[] buffer = new byte;
                  int len = 0;
                  while((len = inStream.read(buffer)) != -1){
                        accessFile.write(buffer, 0, len);
                  }
                  accessFile.close();
                  inStream.close();
                }
                System.out.println("第"+(threadid+1)+"部分下载完成");
            } catch (Exception e) {
                e.printStackTrace();
            }
      }
    }

    private String getFilename(String path) {
      return path.substring(path.lastIndexOf("/")+1);
    }
}
页: [1]
查看完整版本: 多线程下载