多线程模拟迅雷下载
知识点:1.运用swt设计下载界面
2.资源用HttpUrlConnection获取,并设置相应属性
3.断点和续传(暂停或关掉界面后,将下载路径、保存路径、文件总长度和以下载长度保存到txt文件中。下次开启时自动去检索有没有为下载完成的文件。)
4.续传时,请求头换setRequestProperty(“Range”, “bytes=” + start + “-” + totalSize),即从断点那里开始,下面的输入流也相应跳过以下载长度。
具体代码如下:
界面类:
public class XunLei {
private Display display;
protected Shell shell;
private Text text;
private Table table;
private Task task;
private Thread thread;
private ProgressBar bar;
private int totalSize;
private int size;
private String path;
private String url;
private Map<String, Task> map = new HashMap<String, Task>();
/**
* Launch the application.
* @param args
/
public static void main(String[] args) {
try {
XunLei window = new XunLei();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Open the window.
/
public void open() {
display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/*
* Create contents of the window.
*/
protected void createContents() {
shell = new Shell(SWT.MIN);
shell.setImage(SWTResourceManager.getImage(XunLei.class, "/images/yc.png"));
shell.setSize(900,600);
shell.setText("迅雷下载工具");
shell.setLayout(new FillLayout(SWT.HORIZONTAL));
shell.setLocation((display.getClientArea().width-shell.getSize().x)/2, (display.getClientArea().height-shell.getSize().y)/2);
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new FillLayout(SWT.HORIZONTAL));
SashForm sashForm = new SashForm(composite, SWT.NONE);
sashForm.setOrientation(SWT.VERTICAL);
Composite composite_1 = new Composite(sashForm, SWT.NONE);
Label lblNewLabel = new Label(composite_1, SWT.NONE);
lblNewLabel.setBounds(20, 12, 61, 17);
lblNewLabel.setText("下载地址:");
text = new Text(composite_1, SWT.BORDER);
text.setText("https://dl.360safe.com/360sd/360sd_std_5.0.0.8061.exe");
text.setBounds(88, 10, 692, 23);
Button btnNewButton = new Button(composite_1, SWT.NONE);
btnNewButton.setBounds(793, 7, 80, 27);
btnNewButton.setText("下载");
Composite composite_2 = new Composite(sashForm, SWT.NONE);
composite_2.setLayout(new FillLayout(SWT.HORIZONTAL));
table = new Table(composite_2, SWT.BORDER | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn tblclmnNewColumn = new TableColumn(table, SWT.NONE);
tblclmnNewColumn.setWidth(287);
tblclmnNewColumn.setText(" 下载地址");
TableColumn tblclmnNewColumn_2 = new TableColumn(table, SWT.CENTER);
tblclmnNewColumn_2.setWidth(242);
tblclmnNewColumn_2.setText("保存路径");
TableColumn tblclmnNewColumn_1 = new TableColumn(table, SWT.CENTER);
tblclmnNewColumn_1.setWidth(271);
tblclmnNewColumn_1.setText("下载进度");
TableColumn tblclmnNewColumn_3 = new TableColumn(table, SWT.CENTER);
tblclmnNewColumn_3.setWidth(88);
tblclmnNewColumn_3.setText("状态");
final TableCursor tableCursor = new TableCursor(table, SWT.NONE);
Menu menu = new Menu(tableCursor);
tableCursor.setMenu(menu);
final MenuItem menuItem = new MenuItem(menu, SWT.NONE);
menuItem.setText("暂停");
MenuItem menuItem_1 = new MenuItem(menu, SWT.NONE);
menuItem_1.setText("删除");
final MenuItem mntmNewItem = new MenuItem(menu, SWT.NONE);
mntmNewItem.setText("继续");
sashForm.setWeights(new int[] {52, 517});
File file = new File("D:\\xunlei");
if (file.exists()) {
File[] files = file.listFiles();
TableItem ti = null;
for (File f : files) {
if (f.isFile()) {
try {
BufferedReader br = new BufferedReader(new FileReader(f));
ti = new TableItem(table, SWT.NONE);
url = br.readLine();
ti.setText(0,url);
ti.setData("url", url);
ti.setText(1,br.readLine());
TableEditor ted = new TableEditor(table);
bar = new ProgressBar(table, SWT.NONE);
bar.setMinimum(0);
bar.setMaximum(100);
ti.setData("bar", bar);
ted.grabHorizontal = true;
ted.grabVertical = true;
ted.setEditor(bar, ti, 2);
totalSize = Integer.parseInt(br.readLine());
size = Integer.parseInt(br.readLine());
ti.setData("size", size);
ti.setData("totalSize", totalSize);
int count = (int)((size/(float)totalSize)*100);
bar.setSelection( count);
ti.setText(3, "已暂停");
br.close();
f.delete();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
btnNewButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
url = text.getText().trim();
if (url == null || "".equals(url)) {
MessageDialog.openError(shell, "温馨提示", "请输入你要下载的资源地址...");
return;
}
DirectoryDialog fd = new DirectoryDialog(shell, SWT.SAVE);
fd.setText("下载路径选择");
fd.setFilterPath("SystemDrive");
fd.setMessage("请选择你要保存的路径");
path = fd.open();
if (path == null || "".equals(path)) {
return;
}
// 开启启动下载任务
task = new Task(url, path, table);
map.put(url.substring(url.lastIndexOf("/") + 1), task);
thread = new Thread(task);
thread.start();
}
});
menuItem.addSelectionListener(new SelectionAdapter() {
@SuppressWarnings("deprecation")
@Override
public void widgetSelected(SelectionEvent e) { // 暂停
TableItem ti = tableCursor.getRow();
task.save(ti, thread);
thread.stop();
}
});
mntmNewItem.addSelectionListener(new SelectionAdapter() { // 继续
@Override
public void widgetSelected(SelectionEvent e) {
TableItem ti = tableCursor.getRow();
task = new Task(String.valueOf(ti.getData("url")), ti.getText(1), table, ti, Integer.parseInt(String.valueOf(ti.getData("size"))), Integer.parseInt(String.valueOf(ti.getData("totalSize"))),(ProgressBar)ti.getData("bar"));
ti.setText(3, "正在下载");
File file = new File("D:\\xunlei");
if (file.exists()) {
File[] files = file.listFiles();
for (File f : files) {
f.delete();
}
}
thread = new Thread(task);
thread.start();
}
});
shell.addShellListener(new ShellAdapter() {
@Override
public void shellClosed(ShellEvent e) {
TableItem[] tis = table.getItems();
for (TableItem ti : tis) {
if ("正在下载".equals(ti.getText(3))) {
task.save(ti, thread);
}
}
}
});
}
}
线程类:
public class Task implements Runnable{
private String urlPath;
private String savePath;
private Table table;
private ProgressBar bar;
private TableItem ti;
private String fileName;
private int totalSize = 0;
private int size = 0;
private int start = 0;
private boolean flag = true;
private boolean isPause = false;
public Task(String urlPath, String savePath, Table table) {
this.urlPath = urlPath;
this.fileName = urlPath.substring(urlPath.lastIndexOf("/") + 1);
this.savePath = savePath + “\” + fileName;
this.table = table;
flag = true;
start = 0;
}
public Task(String urlPath, String savePath, Table table, TableItem ti, int start, int totalSize, ProgressBar bar) {
this.urlPath = urlPath;
this.fileName = urlPath.substring(urlPath.lastIndexOf("/") + 1);
this.savePath = savePath;
this.table = table;
this.ti = ti;
this.start = start + 1;
this.size = start;
this.totalSize = totalSize;
this.bar = bar;
flag = false;
ti.setData(“totalSize”, totalSize);
}
@Override
public void run() {
table.getDisplay().asyncExec(new Runnable(){
@Override
public void run() {
if (flag) {
ti = new TableItem(table, SWT.NONE);
ti.setText(0, fileName);
ti.setData(“url”, urlPath);
ti.setText(1, savePath);
ti.setText(3, “正在下载”);
TableEditor ted = new TableEditor(table);
bar = new ProgressBar(table, SWT.NONE);
bar.setMinimum(0);
bar.setMaximum(100);
ted.grabHorizontal = true;
ted.grabVertical = true;
ted.setEditor(bar, ti, 2);
ti.setData("bar", bar);
}
}
});
FileOutputStream fos = null;
InputStream is = null;
HttpURLConnection con = null;
try {
URL url = new URL(urlPath);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(5 * 1000);
if (flag) {
con.connect();
totalSize = con.getContentLength();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
ti.setData("totalSize", totalSize);
}
});
} else {
con.setRequestProperty("Range", "bytes=" + start + "-" + totalSize);
con.setUseCaches(true);
}
is = con.getInputStream();
RandomAccessFile raf = new RandomAccessFile(savePath, "rwd");
//[6]每个线程要从自己的位置开始写
raf.seek(start);
//[7]把数据写到文件中
int len = -1;
byte[] buffer = new byte[1024*1024];//1Mb
while((len = is.read(buffer))!=-1){
raf.write(buffer, 0, len);
size += len;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
int count = (int)((size/(float)totalSize)*100);
bar.setSelection( count);
if (count == 100) {
ti.setText(3, "已下载");
}
// 保存已下载大小
ti.setData("size", size);
}
});
}
raf.close();//关闭流 释放资源
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (con != null) {
con.disconnect();
}
}
}
public void save(TableItem ti, Thread thread) {
File file = new File("D:\\xunlei");
if (!file.exists()) {
file.mkdir();
}
ti.setText(3, "已暂停");
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\xunlei\\"+fileName+".txt"));
bw.write(String.valueOf(ti.getData("url"))+"\r\n");
bw.write(ti.getText(1)+"\r\n");
bw.write(String.valueOf(ti.getData("totalSize"))+"\r\n");
bw.write(String.valueOf(ti.getData("size")));
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
上一篇: Freemarker生成商品详情静态页面
下一篇: php短址转换实现方法_PHP