首页>代码>利用java swing多线程实现的下载器,完爆迅雷!>/DowmloadURLFile/src/download/multithread/DownloadFileThread.java
package download.multithread;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import download.ui.GUI;


public class DownloadFileThread extends Thread{

	//网络文件地址
	public String urlFile;
	
	//当前线程的开始下载点
	private long startPos;
	
	//当前线程的结束下载点
	private long endPos;
	
	//当前线程下载文件的完整路径及名字
	private String currentFileTreadName;
	
	//当前是第几个线程
	public int currentThread;
	
	//类构造函数
	public DownloadFileThread(String urlFile,long startPos,long endPos, String currentFileThreadName,int currentThread){
		
		this.urlFile = urlFile;
		this.startPos = startPos;
		this.endPos = endPos;
		this.currentFileTreadName = currentFileThreadName;
		this.currentThread = currentThread;
	}
	
	//判断文件是否存在 - 判断文件名:currentFileThreadName.tp
	private boolean fileExist(String pathAndFile){
		return new File(pathAndFile).exists();
	}
	
	//获取文件大小
	private long fileSize(String pathAndFile){
		return new File(pathAndFile).length();
	}
	
	//重命名文件 - 下载完成 - 命名规则:currentFileThreadName
	private void fileRename(String fromName,String toName){
		new File(fromName).renameTo(new File(toName));
	}
	
	//线程启动调用的方法
	public void run(){
		
		GUI.showLog(this.currentThread + "号线程下载开始");
		
		BufferedInputStream bis = null;
		RandomAccessFile raf = null;
		String paf = "";
		long offset = 0;
		
		try {
			//获取与所需下载的网络上资源的连接
			URLConnection con = new URL(urlFile).openConnection();
			log(this.currentThread + "连接成功");
			
			//计算该线程需要下载内容的大小
			offset = this.endPos - this.startPos + 1;
			log(this.currentThread + "下载大小=" + offset);
			
			if(!this.fileExist(this.currentFileTreadName)){

				// 判断临时文件的存在
				paf = this.currentFileTreadName + ".tp";
				long length = 0;// 已下载长度
				if (this.fileExist(paf)) {

					length = this.fileSize(paf);
					
					raf = new RandomAccessFile(new File(paf), "rw");
					//指定插入位置
					raf.seek(length);
					
					//重新计算开始下载点
					this.startPos = this.startPos + length;
					log(this.currentThread + "断点续传,已存在=" + length);
				}else{
					
					//新建缓存文件
					raf = new RandomAccessFile(new File(paf), "rw");
				}

				// 开始下载资源
				bis = new BufferedInputStream(con.getInputStream());
				bis.skip(this.startPos);
				log(this.currentThread + "跳到开始下载点=" + startPos);

				int blength;// 缓存实际长度
				int BUFF = 2048;
				byte bytes[] = new byte[BUFF];

				log(this.currentThread + "length=" + length + "startPos=" + startPos + "&endPos=" + endPos);
				while (true) {

					// 下载至缓存
					blength = bis.read(bytes);
//					log("下载至缓存,长度=" + blength + ", 先前已下载=" + length);

					// 缓存至文件
					if ((length += blength) < offset) {

//						log("缓存至文件");
						raf.write(bytes, 0, blength);

					} else {

						if(length==offset){
							
							log(this.currentThread + "#1缓存至文件,最后输入长度=" + blength);
							raf.write(bytes, 0, blength);
							
						}else{
							log(this.currentThread + "blenth=" + blength + "&length=" + length + "&offset=" + offset + "&BUFF=" + BUFF);
							log(this.currentThread + "#2缓存至文件,最后输入长度=" + (blength-(int)(length-offset)));						
							raf.write(bytes, 0,blength-(int)(length-offset));
						}
						break;
					}
				}
				log(this.currentThread + "下载结束,文件名=" + paf + ",文件长度=" + this.fileSize(paf));
			}else{
				
				log(this.currentThread + "该临时文件已下载");
			}
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			log(this.currentThread + "获取URL失败");
			GUI.showLog(this.currentThread + "号线程下载出错了 ...");
		} catch (IOException e) {
			// TODO Auto-generated catch block
//			e.printStackTrace();
			log(this.currentThread + "获取连接或下载时异常");
			GUI.showLog(this.currentThread + "号线程下载出错了 ...");
		} finally{
			
			if(bis!=null){
				try {
					bis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(raf!=null){
				try {
					raf.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		log(this.currentThread + "输入输出流关闭");
		
		//下载结束,判断临时文件大小
		if(this.fileSize(paf)==offset){
			
			log(this.currentThread + "重命名文件");
			
			//重命名文件
			this.fileRename(paf, this.currentFileTreadName);
			
			GUI.showLog(this.currentThread + "号线程下载完成");
			
		}else{
			
			//下载失败
			log(this.currentThread + "下载失败");
			
			GUI.showLog(this.currentThread + "号线程下载出错 ...");
		}
		
		//更新在调度线程中的状态
		GetFileDispatchThread.checkList[this.currentThread] = true;
		
		log(this.currentThread + "线程结束");
	}
	
	/*
	 * 日志
	 */
	boolean showLog = false;
	
	public void log(String msg){
		if(this.showLog)System.out.println(msg);
	}
	
//	/**
//	 * @param args
//	 */
//	public static void main(String[] args) {
//		// TODO Auto-generated method stub
//		
//		//测试方法 - 下载URL文件的一段
//		new DownloadFileThread("http://192.168.28.121/eclipse.rar", 50 , 200, "eclipse3", 3).start();
//		
//		/*
//		 * 下载结束,文件长度为0
//		 * 
//		 * 		原因:判读长度前,关闭输入输出流
//		 */
////		System.out.println(new File("E:\\Workspace\\DowmloadURLFile\\eclipse2.tp").length());
//	}

}
最近下载更多
snowing_for  LV9 2024年11月25日
刘先生-OL  LV13 2024年11月25日
刘孟飞  LV22 2024年6月21日
愚人劫  LV1 2023年5月30日
Xgcxgc  LV1 2023年3月28日
MoonSight  LV1 2022年7月1日
liys1234  LV9 2022年4月25日
bai620123  LV16 2022年4月16日
一个好人520  LV10 2021年9月29日
qq8945051  LV1 2021年9月11日
最近浏览更多
snowing_for  LV9 2024年11月25日
刘先生-OL  LV13 2024年11月25日
刘孟飞  LV22 2024年6月21日
pangzhihui  LV14 2023年12月14日
愚人劫  LV1 2023年5月30日
Xgcxgc  LV1 2023年3月28日
xingxing1234  LV10 2023年3月22日
liuind 2023年3月17日
暂无贡献等级
MoonSight  LV1 2022年7月1日
fantaohaofan  LV2 2022年6月23日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友