测试多线程下载的Java类


Java多线程下载的基础类,类似于迅雷,QQ旋风等下载器一样的原理。
 
package com.shenzhen.mutiledownload2014;
 
import java.io.InputStream;
 import java.io.RandomAccessFile;
 import java.net.HttpURLConnection;
 import java.net.URL;
 
/**
  * 测试多线程下载的样例
  *
 * @author mayubao
  *
 */
 public class TestDownload {
 
    public static final String path = "http://192.168.1.120:8080/a.zip";
 
    public static final void main(String[] args) throws Exception {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打开一个链接
 
        // 设置一个请求的相关信息
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(5000);
        // User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
        // Gecko/20100101 Firefox/29.0
 
        conn.setRequestProperty("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
 
        int code = conn.getResponseCode();
 
        if (code == 200) {// 请求过去且回复内容正常的话
            int len = conn.getContentLength();
            RandomAccessFile file = new RandomAccessFile("D:/temp/test/"
                    + getFileName(path), "rwd");
 
            // 1.创建一个本地文件跟服务器的大小一致
            file.setLength(len);
 
            // 2.根据服务器中要下载的文件大小划分要多少个线程
            int threadnum = 3;
            int blocksize = len / threadnum;
 
            /**
              * 多线程下载 线程1 0 ~ blocksize 线程2 blocksize*1 ~ blocksize*2 线程3
              * blocksize*2 ~ len
              */
            for (int i = 0; i < threadnum; i++) {
                int startposition = i * blocksize;
                int endposition = (i + 1) * blocksize;
                if (i == (threadnum - 1)) {// 最后一个线程的话,那么就另endposition=len
                    endposition = len;
                }
 
                // 分别执行每一个线程
 
                new DownloadTask(i, path, startposition, endposition).start();
            }
 
        }
        // conn.setRequestProperty(key, value);
 
    }
 
    public static String getFileName(String path) {
        int start = path.lastIndexOf("/");
        return path.substring(start, path.length());
    }
 
}
 

/**
  * 下载的线程类
  *
 * @author mayubao
  *
  */
 class DownloadTask extends Thread {
 
    private int id;
    private String path;
    private int startposition;
    private int endposition;
 
    public DownloadTask(int id, String path, int startposition, int endposition) {
        this.id = id;
        this.path = path;
        this.startposition = startposition;
        this.endposition = endposition;
    }
 
    @Override
    public void run() { // 每一个线程体要执行的内容
        URL url;
        try {
            url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 
            // 设置一个请求的相关信息
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            // User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0)
            // Gecko/20100101 Firefox/29.0
 
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
 
            InputStream is = conn.getInputStream();
            RandomAccessFile file = new RandomAccessFile(getFileName(path),
                    "rwd");
 
            file.seek(startposition);
 
            // 将反馈回来的输入流写到RandomAccessFile里面去
            byte[] buffer = new byte[1024];
            int len = 0;
 
            while ((len = is.read(buffer)) != -1) {// 输入流没到尽头
                file.write(buffer, 0, len);
            }
 
            file.close();
 
            System.out.println("第" + id + "个线程已经下载完成了");
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.run();
    }
 
    public static String getFileName(String path) {
        int start = path.lastIndexOf("/");
        return path.substring(start, path.length());
    }
 
}

Java1.5后的多线程框架

Java多线程和同步的理解

Java中两种实现多线程方式的对比分析

Java利用多线程计算目录数据大小

Java多线程向数据库写入数据

Java多线程经典案例

本文永久更新链接地址:

相关内容