http:多线程下载器


ThreadId:0,1,2
int block = 4; 每个线程下载的数据量
int start = ThreadId * block; 每个线程下载的起始位置
0*4 = 0  0开始下载
1*4 = 4  4开始下载
2*4 = 8  8开始下载
int end = (ThreadId+1) * block -1;
(0+1)*4-1 = 3   3是线程0下载结束位置
(1+1)*4-1 = 7   7是线程1下载结束位置


conn.getContentLength(); 获取要下载文件的大小API


随机访问文件类RandomAccessFile(File file,String mode)

文件包含两部分:元数据(日期,作者,等),数据

mode:推荐rwd

r     :只读方式

rw  :读写方式

rws:要求对文件的内容-元数据每个更新都同步到存储设备

rwd:要求对文件的内容的每个更新同步到存储设备(每次更新不包含元数据)


DownloadThread.java

package netdown;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * threadId:开启的每条线程的id
 * block:每条线程下载的数据量
 * url	:下载原地址
 * file	:要保存的本地文件
 * run() 执行下载
 * conn.setRequestMethod("GET")
 * conn.setRequestProperty(Range:范围,开始位置-结束位置)
 * InputStream inStream = conn.getInputStream(); 从conn获得 输入流
 * inStream.read();
 */
public class DownloadThread extends Thread{
	int threadId; 
	int block;
	URL url; 
	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);//文件指针指向start位置开始写入
			//发起请求
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET"); 
			conn.setRequestProperty("Range", "bytes="+start+"-"+end);
			//分段下载请求码是206
			if(conn.getResponseCode() == 206){
			System.out.println(conn.getResponseCode());
				//从conn获得 输入流
				InputStream inStream = conn.getInputStream();
				
				byte[] buffer = new byte[1024];//缓冲区
				int len = 0;//起始0 --- 缓冲区读取结束
				while( (len = inStream.read(buffer)) != -1){
					accessFile.write(buffer, 0, len);//buffer 写入 文件
				}
				accessFile.close();
				inStream.close();
			}
			System.out.println("Thread:"+(threadId+1)+"下载完成!");
		} catch (Exception e) {
			e.printStackTrace();
		}
		super.run();
	}
}
MultThreadDownload.java //多线程下载

package netdown;

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

public class MultThreadDownload {
	
	public static void main(String[] args) {
		String path = "http://192.168.1.4:8080/apache-tomcat-8.0.11-windows-i64.zip";
		new MultThreadDownload().download(path,3);
	}

	/**
	 * 下载文件 内部方法
	 * @param path 网络文件路径
	 * @param ThreadCount 开启几条线程
	 * DownloadThread 创建的线程calss
	 */
	private void download(String path,int ThreadCount) {
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET"); 
			if(conn.getResponseCode() == 200){
				//API获取服务器返回下载的文件的大小,getContentLength();
				int  length = conn.getContentLength();
				//本地生成与网络文件相同大小的文件
				File file = new File(getFilename(path));
				RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
				accessFile.setLength(length);//本地生成文件
				accessFile.close();
				//计算每条线程下载的数据量
				int block = length%ThreadCount == 0 ? length/ThreadCount : length/ThreadCount+1;
				for (int ThreadId = 0; ThreadId < ThreadCount; ThreadId++) {
					new DownloadThread(ThreadId,block,url,file).start();
				}
			}else{
				System.out.println("下载失败!");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * @param path 全路径
	 * @return path 下载文件名称(过滤掉http地址,取得下载文件名称)
	 */
	private String getFilename(String path) {
		return path.substring(path.lastIndexOf("/")+1);
	}
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值