java实现多线程下载技术

        多线程下载技术,简单的说就是把要下载的文件分成几块,由不同的线程来负责每一块数据的下载任务。

        要使用一个随机访问文件的类:RandomAccessFile类,具体用法请参考:http://blog.csdn.net/java4found/article/details/8656695

        具体思路:

             1、文件分块。 文件分块大小block = 文件大小 % 线程数 == 0 ? 文件大小 / 线程数 : 文件大小 / 线程数 + 1 ; 

             2、确定每一个线程下载对应用文件的位置指针。

                     现假设为每个线程分别编号threadid     0 1 2 3 4

                     则第一个线程负责的下载位置是: 0*分块大小  到  (0+1)*分块大小-1

                     第二个线程负责的下载位置是: 1*分块大小   到  (1+1)*分块大小-1

                           即有开始下载位置 start = threadid*block;

                           即有结束下载位置 end = (threadid+1)*block-1;

             3、最后通过设置连接的属性, conn.setRequestProperty("Range", "bytes=" + start + "-" + end);

简易的多线程下载代码如下:

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


public class MultiThread {
	public static void main(String[] args) {
		//文件下载路径
		String filePath = "http://dldir1.qq.com/qqfile/qq/QQ2013/QQ2013Beta2.exe";
		//文件保存路径
		String destination = "D:";
		//打算开启的线程数
		int threadNum = 5;
		new MultiThread().download(filePath, destination, threadNum);
	}

	/**
	 * 下载文件
	 */
	private void download(String filePath, String destination, int threadNum) {
		try {
			//通过下载路径获取连接
			URL url = new URL(filePath);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			//设置连接的相关属性
			conn.setRequestMethod("GET");
			conn.setReadTimeout(5000);
			//判断连接是否正确。
			if (conn.getResponseCode() == 200) {
				// 获取文件大小。
				int fileSize = conn.getContentLength();
				//得到文件名
				String fileName = getFileName(filePath);
				//根据文件大小及文件名,创建一个同样大小,同样文件名的文件
				File file = new File(destination + File.separator + fileName);
				RandomAccessFile raf = new RandomAccessFile(file, "rw");
				raf.setLength(fileSize);
				raf.close();
				// 将文件分成threadNum = 5份。
				int block = fileSize % threadNum == 0 ? fileSize / threadNum
						: fileSize / threadNum + 1;
				for (int threadId = 0; threadId < threadNum; threadId++) {
					//传入线程编号,并开始下载。
					new DownloadThread(threadId,block, file, url).start();
				}

			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//由路径获取文件名。
	private String getFileName(String filePath) {
		return filePath.substring(filePath.lastIndexOf('/') + 1);
	}

}

//文件下载线程
class DownloadThread extends Thread {
	int start, end,threadId;
	File file = null;
	URL url = null;

	public DownloadThread(int threadId,int block, File file, URL url) {
		this.threadId = threadId;
		start = block * threadId;
		end = block * (threadId + 1) - 1;
		this.file = file;
		this.url = url;
	}

	public void run() {
		try {
			//获取连接并设置相关属性。
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setReadTimeout(5000);
			//此步骤是关键。
			conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
			if (conn.getResponseCode() == 206) {
				RandomAccessFile raf = new RandomAccessFile(file, "rw");
				//移动指针至该线程负责写入数据的位置。
				raf.seek(start);
				//读取数据并写入
				InputStream inStream = conn.getInputStream();
				byte[] b = new byte[1024];
				int len = 0;
				while ((len = inStream.read(b)) != -1) {
					raf.write(b, 0, len);
				}
				System.out.println("线程"+threadId+"下载完毕");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}



  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值