java 多线程下载

多线程下载,我们主要使用到HttpURLConnection、线程、RandomAccessFile这几部分的知识。普通的下载和多线程下载,就像多个水管和一个水管抽水一样,多个管子同时运作,效率自然比一个管子快的多,但受限于水管的粗细,所以水流量也不会太夸张。

话不多说,直接上代码:

package org.testDt;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
 * @author jzw
 */
public class TestRandomDown {
	
	public void multiDown(final String sourcePath,String savePath,int threadNum) {
		final File file = new File(savePath);
		try {
			URL url = new URL(sourcePath);
			HttpURLConnection huc = (HttpURLConnection) url.openConnection();
			//获取响应码和文件大小
			int responseCode = huc.getResponseCode();
			final int fileSize = huc.getContentLength();
			huc.disconnect();
			//给线程划分下载块
			int blockSize = (fileSize + threadNum - 1)/threadNum;
			if (responseCode == 200) {
				for (int i = 0;i < threadNum;i++) {
					final int a = i;
					final int start = blockSize * a;// 开始位置
					final int end = blockSize * (a + 1) - 1;// 结束位置
					//每个线程使用一个RandomAccessFile进行下载
					new Thread(new Runnable() {
						@Override
						public void run() {
							try {
								URL url = new URL(sourcePath);
								HttpURLConnection huc1 = (HttpURLConnection) url.openConnection();
								//设置请求返回的文件大小范围
								huc1.setRequestProperty("Range", "bytes="+start+"-"+end+"");
								InputStream in = huc1.getInputStream();
								/*
								 * 创建一个存储资源文件对应的虚拟文件,该文件可用来随机访问文件的读取和写入
								 * "rwd",打开以便读取和写入,保证由该调用对此文件所做的所有更改均被写入底层存储设备中
								 */
								RandomAccessFile acf = new RandomAccessFile(file,"rwd");
								//设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作
								//在这里file中最后就存储了所有线程下载的文件
								acf.seek(start);
								byte[] buffer = new byte[1024];
								int len = 0;
								while((len=in.read(buffer)) != -1) {
									acf.write(buffer, 0, len);
								}
								System.out.println("线程:" + a + "下载完成!");
								acf.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}).start();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		TestRandomDown t= new TestRandomDown();
		t.multiDown("http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/20.gif", 
				"D://testXiaZai/20.gif", 3);
	}
}

至于断点下载,无非是用配置文件或变量记录下文件的下载进度,即每个线程下载到了哪个字节数,等重新开始下载时,在该位置的下一个字节数继续下载即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值