首页 > 技术文章 > java 多线程下载

ch94 2018-12-11 16:17 原文

package downLoad;

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

public class ThreadDownLoader extends Thread {
    private String path;
    private int startIndex;
    private int endIndex;
    private int threadId;
    private int threadCount;
    // 正在运行的线程个数
    private static int runningThreadCount = 3;

    ThreadDownLoader(String path, int startIndex, int endIndex, int threadId, int threadCount) {
        this.path = path;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
        this.threadId = threadId;
        this.threadCount = threadCount;

    }

    @Override
    public void run() {
        downLoad(path, startIndex, endIndex, threadId, threadCount);
    }

    public void downLoad(String path, int startIndex, int endIndex, int threadId, int threadCount) {
        try {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestMethod("GET");
            conn.setConnectTimeout(3000);
            // 设置子线程请求数据的范围
            conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
            int code = conn.getResponseCode();
            if (code == 206) {// 请求部分数据

                InputStream is = conn.getInputStream();
                RandomAccessFile file = new RandomAccessFile("temp.exe", "rw");
                // 指定从哪个位置开始写数据
                file.seek(startIndex);

                byte[] buffer = new byte[1024];
                int len = -1;
                while ((len = is.read(buffer)) != -1) {
                    file.write(buffer, 0, len);
                }

                file.close();
                System.out.println("线程" + threadId + "下载完成...............");
                synchronized (ThreadDownLoader.this) {
                    runningThreadCount--;
                    if (runningThreadCount == 0) {
                        System.out.println("文件下载完成...............");
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("线程" + threadId + "下载失败...............");
            e.printStackTrace();
        }

    }
}

 

package downLoad;

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

public class MultiThreadDownLoader {
	
	// 2、使用的子线程的个数
	private static int threadCount = 3;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			String path = "https://download.jetbrains.8686c.com/idea/ideaIU-2018.3.1.exe";//文件路径
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(3000);

			int code = conn.getResponseCode();
			if (code == 200) {
				int length = conn.getContentLength();
				// 1、在客户端创建一个与服务端文件一样大小的文件
				RandomAccessFile file = new RandomAccessFile("temp.exe", "rw");
				file.setLength(length);
				// 3、每个子线程下载数据块 ,下载的起始位置和结束位置
				int blockSize = length / threadCount;

				// threadId * blockSize ---- (threadId+1)* blockSize -1
				for (int threadId = 0; threadId < threadCount; threadId++) {
					// 下载的起始位置和结束位置
					int startIndex = threadId * blockSize;
					int endIndex = 0;

					if (threadId != (threadCount - 1)) {
						endIndex = (threadId + 1) * blockSize - 1;
					} else {
						endIndex = length - 1;
					}

					// 开启子线程下载数据
					new ThreadDownLoader(path, startIndex, endIndex, threadId, threadCount).start();

				}

			} else {
				// 抛出异常
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

  

推荐阅读