Android/Java多线程下载

package com.lipeng.download;

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


/**
 * 多线程下载
 * @author Dell
 */
public class MulThreadDownload {
	public static void main(String[] args) {
		String path = "http://192.168.188.1:8080/test/FeiQ.exe"; 
		int threadSize = 3;
		try {
			new MulThreadDownload().download(path, threadSize);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 下载文件
	 * @param path 下载路径
	 * @param threadSize 线程个数
	 * @throws Exception
	 */
	private void download(String path, int threadSize) throws Exception {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5000);
		conn.setRequestMethod("GET");
		if(conn.getResponseCode() == 200){
			int contentLength = conn.getContentLength();	// 获取下载文件的内容长度
			File file = new File(getFileName(path));
			// rwd方式:打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。 
			// Android 程序要使用rwd方式,防止文件丢失
			RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rwd");
			randomAccessFile.setLength(contentLength);	// 设置该文件的长度等于下载文件的长度
			randomAccessFile.close();
			
			int block = contentLength%threadSize==0 ? contentLength/threadSize : contentLength/threadSize + 1;
			// 设置每个县城下载的数量
			for(int threadId=0; threadId<threadSize; threadId++){
				DownloadThread thread = new DownloadThread(threadId, block, url, file);
				thread.start();
			}
		} else {
			System.out.println("下载失败");
		}
	}
	
	private class DownloadThread extends Thread{
		private int threadId;
		private int block; 
		private URL url;
		private File file;
		/**
		 * @param threadId 线程ID
		 * @param block 每个线程下载数据量
		 * @param url 下载路径
		 * @param file 下载存放文件
		 */
		public DownloadThread(int threadId, int block, URL url, File file){
			this.threadId = threadId;
			this.block = block;
			this.url = url;
			this.file = file;
		}
		
		@Override
		public void run() {
			int startLocation = threadId * block;	// 从网络文件的开始下载位置
			int endLocation = (threadId + 1) * block - 1;	// 到网络文件下载的结束位置
			
			try {
				RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rwd");
				randomAccessFile.seek(startLocation);
				
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(5000);
				conn.setRequestMethod("GET");
				conn.setRequestProperty("Range", "bytes=" + startLocation + "-" + endLocation);
				
				// 写入文件
				InputStream in = conn.getInputStream();
				int len;
				byte[] buffer = new byte[1024];
				while((len=in.read(buffer)) != -1){
					randomAccessFile.write(buffer, 0, len);
				}
				randomAccessFile.close();
				in.close();
				
				System.out.println("第" + (threadId + 1) + "线程下载完成");
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}

	/**
	 * 获取文件名称
	 * @param path
	 * @return
	 */
	private String getFileName(String path) {
		if(path != null && !"".equals(path)){
			return path.substring((path.lastIndexOf("/") + 1));	
		}
		return null;
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值