首页>代码>利用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());
//	}

}
最近下载更多
愚人劫  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日
Kervin  LV11 2021年6月3日
尹恒yingying  LV18 2021年4月8日
test66728  LV1 2021年2月2日
最近浏览更多
pangzhihui  LV12 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日
liys1234  LV9 2022年4月25日
bai620123  LV16 2022年4月16日
zhendong  LV7 2022年3月10日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友