⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloadfile.java

📁 该多线程下载工具功能强大
💻 JAVA
字号:
package coursedesign;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Observable;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import javax.swing.Timer;

public class DownLoadFile extends Observable implements Runnable {

	// 保存路径
	private String saveURL;

	// 下载线程数
	private int nthread;

	// 线程开始下载点
	private long[] startPos;

	// 线程结束下载点
	private long[] endPos;

	// 下载线程
	private DownLoadFileThread[] downFileSplitter;

	// 时间计时器
	private Timer timer;

	// 已下载时间
	private String time = "00:00:00";

	// 下载剩余时间
	private String leavetime = "--:--:--";

	// 下载用时
	private int second = 0;

	// 设置下载的各种状态.
	public static final String STATUSES[] = { "下载中", "暂停", "完成", "取消", "错误" };

	// 定义各种状态的代号
	public static final int DOWNLOADING = 0;

	public static final int PAUSED = 1;

	public static final int COMPLETE = 2;

	public static final int CANCELLED = 3;

	public static final int ERROR = 4;

	// 要下载的URL地址
	private String url;

	// 下载文件的大小 bytes
	private long size;

	// 已经下载的文件文件的bytes
	private int downloaded;

	// 临时下载量
	private int tmp = 0;

	// 定义一个整形变量用来接受状态代码
	private int status;

	// 下载文件名(有扩展名)
	private String fileName;

	// 下载文件名(无扩展名)
	private String filename;

	OperateProperties op;

	// 时间设置
	Calendar cl, c2;

	// 定义下载保存数组
	int a[];

	int b[];

	// 定义下载速度
	int speed = 1;

	SimpleDateFormat myFmt;

	// 构造器

	public DownLoadFile() {
	}

	public DownLoadFile(String URL, String saveURL, int nthread,
			int downloaded, int size, int status, int s[], int second) {

		this.url = URL;
		this.saveURL = saveURL;
		this.nthread = nthread;
		this.startPos = new long[nthread];
		this.endPos = new long[nthread];
		this.downloaded = downloaded;
		this.size = size;
		this.status = status;
		a = new int[nthread];
		if (s == null)
			b = new int[nthread];
		else
			this.b = s;

		this.second = second;

		op = new OperateProperties();
		// size = -1;
		// 初始化文件已下载大小为0
		// downloaded = 0;
		// 初始化文件下载状态为“下载中”
		// status = DOWNLOADING;
		// 开始下载

		cl = Calendar.getInstance();
		c2 = Calendar.getInstance();
		// 时间进行归零
		cl.setTimeInMillis(16 * 60 * 60 * 1000);
		c2.setTimeInMillis(16 * 60 * 60 * 1000);
		// 设置时间显示格式
		myFmt = new SimpleDateFormat("HH:mm:ss");
		cl.add(Calendar.SECOND, second);
		download();

	}

	// 返回文件名
	public String getFileName() {

		String[] s = saveURL.split("\\\\");
		int i = s.length;
		fileName = s[i - 1];
		return fileName;
	}

	// 返回剩余时间
	public String getLeaveTime() {

		return leavetime;
	}

	// 返回所用时间
	public String getTime() {

		return time;
	}

	// 返回url地址的字符串形式
	public String getUrl() {
		return url.toString();
	}

	// 返回即时速度
	public int getSpeed() {

		return speed;

	}

	// 返回线程数
	public int getThread() {
		return nthread;
	}

	// 返回文件大小
	public long getSize() {
		return size;
	}

	// 返回已下载文件百分比
	public float getProgress() {

		return ((float) downloaded / size) * 100;
	}

	// 返回下载状态的整形代码
	public int getStatus() {
		return status;

	}

	// 返回文件类型
	public String getFileType() {
		String[] s = fileName.split("\\.");

		String extension = s[1];
		if (extension.equalsIgnoreCase("exe"))
			return "应用程序";
		else if (extension.equalsIgnoreCase("mp3")
				|| extension.equalsIgnoreCase("wma"))
			return "音乐文件";
		else if (extension.equalsIgnoreCase("txt"))
			return "文本文档";
		else if (extension.equalsIgnoreCase("rmvb")
				|| extension.equalsIgnoreCase("avi")
				|| extension.equalsIgnoreCase("rm"))
			return "电影视频文件";
		else if (extension.equalsIgnoreCase("doc"))
			return "Microsoft Word 文档";
		else if (extension.equalsIgnoreCase("xls"))
			return "Microsoft Excel 文档";
		else if (extension.equalsIgnoreCase("ppt"))
			return "Microsoft PowerPoint 文档";
		else if (extension.equalsIgnoreCase("java"))
			return "JAVA 文件";
		else if (extension.equalsIgnoreCase("pdf"))
			return "PDF 文档";
		else if (extension.equalsIgnoreCase("rar")
				|| extension.equalsIgnoreCase("zip"))
			return "压缩文件";
		else
			return extension + "  文件";
	}

	// 设置下载状态为暂停,当侦听器的目标已更改其状态时调用。
	public void pause() {

		status = PAUSED;

	}

	// 设置下载状态为下载中,
	public void resume() {

		status = DOWNLOADING;

		download();
	}

	// 下载状态为取消下载
	public void cancel() {

		status = CANCELLED;

	}

	// 提示下载出错
	private void error() {
		status = ERROR;

	}

	// 开始下载时开始创建线程,进行下载
	private void download() {
		Thread thread = new Thread(this);
		thread.start();

	}

	public void run() {

		try {
			size = getFileSize(url);

			if (size == -1) {

			} else {
				if (size == -2) {

				} else {
					// 分配各线程下载量
					for (int i = 0; i < startPos.length; i++)
						startPos[i] = (long) (i * (size / startPos.length));
					for (int i = 0; i < endPos.length - 1; i++)
						endPos[i] = startPos[i + 1];
					endPos[endPos.length - 1] = size;
					// 实例化各线程
					downFileSplitter = new DownLoadFileThread[startPos.length];

					for (int i = 0; i < startPos.length; i++) {
						// 调用下载子线程
						downFileSplitter[i] = new DownLoadFileThread(url,
								startPos[i] + b[i], endPos[i], saveURL, this);

						stateChanged();
						// 启动线程
						downFileSplitter[i].start();

					}

					timer = new Timer(1000, new ActionListener() {
						@SuppressWarnings("deprecation")
						public void actionPerformed(ActionEvent arg0) {
							// 计算下载时间
							cl.add(Calendar.SECOND, 1);
							Date date1 = cl.getTime();
							time = myFmt.format(date1.getTime());
							// 即时下载量
							int readTotal = 0;
							boolean finished = true;

							for (int i = 0; i < startPos.length; i++) {

								if (downFileSplitter[i].isAlive())
									finished = false;
								tmp = downFileSplitter[i].getReadPos();
								tmp = tmp + b[i];
								a[i] = tmp;
								readTotal += tmp;

							}
							if (downloaded != readTotal)
								// 计算速度
								speed = readTotal - downloaded;
							downloaded = readTotal;
							stateChanged();

							second++;

							if (status == PAUSED) {
								finished = false;

								// 获得无扩展名的文件名
								String[] s = fileName.split("\\.");
								filename = s[0];

								for (int i = 0; i < startPos.length; i++) {
									// 记录各个线程的下载量
									b[i] = a[i];

									/*
									 * @把各个属性保存到磁盘中
									 */
									op.writeProperties(
											filename + ".properties", String
													.valueOf(i + 1), String
													.valueOf(b[i]));
								}

								op.writeProperties(filename + ".properties",
										"saveURL", saveURL);
								op.writeProperties(filename + ".properties",
										"verifiedUrl", url);

								op.writeProperties(filename + ".properties",
										"downloaded", String
												.valueOf(downloaded));
								op.writeProperties(filename + ".properties",
										"fileLength", String.valueOf(size));
								op.writeProperties(filename + ".properties",
										"status", String.valueOf(status));

								op.writeProperties(filename + ".properties",
										"nthread", String.valueOf(nthread));
								op.writeProperties(filename + ".properties",
										"second", String.valueOf(second));

								timer.stop();
							}

							// 下载剩余时间的计算
							int second = (int) (size - downloaded) / speed;
							int hour = second / 60 / 60;
							int minute = second / 60;

							Date date2 = c2.getTime();
							c2.set(1990, 01, 01, hour, minute, second);

							leavetime = myFmt.format(date2.getTime());

							// 下载完成的判断
							if (finished) {
								if ((long) readTotal == size) {

									status = COMPLETE;

									// 删除断点续传记录文件

									File f = new File("e:\\" + filename
											+ ".properties");

									boolean result = false;
									int tryCount = 0;
									while (!result && tryCount++ < 10) {
										System.gc();
										result = f.delete();
									}

									JOptionPane.showMessageDialog(null,
											fileName + "下载完成!!!");
									stateChanged();
								} else
									JOptionPane.showMessageDialog(null,
											"未能完成下载!!!");

								File f1 = new File("e:\\" + filename
										+ ".properties");
								f1.delete();
								timer.stop();

							}
						}

					});
					timer.start();

				}
			}

		} catch (Exception ex) {

		}
	}

	public long getFileSize(String URL) {
		int fileLength = -1;
		try {
			URL url = new URL(URL);
			URLConnection httpConnection = url.openConnection();
			int responseCode = ((HttpURLConnection) httpConnection)
					.getResponseCode();
			if (responseCode >= 400) {
				System.out.println("Web服务器响应错误");
				return -2;// Web服务器响应错误
			}
			String sHeader;
			for (int i = 1;; i++)// 查找标识文件长度的文件头,获取文件长度
			{
				sHeader = httpConnection.getHeaderFieldKey(i);
				if (sHeader != null) {
					if (sHeader.equals("Content-Length")) {
						size = fileLength = Integer.parseInt(httpConnection
								.getHeaderField(sHeader));

						stateChanged();

						break;
					}
				} else {
					break;
				}
			}
		} catch (Exception ex) {
			error();
		}
		return fileLength;

	}

	private void stateChanged() {
		setChanged();
		// 并调用 clearChanged 方法来指示此对象不再改变
		notifyObservers();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -