📄 downloadfile.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 + -