ui界面:
為龍井等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及龍井網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為網(wǎng)站設計、成都網(wǎng)站制作、龍井網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
package DownLoaderItem;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
public class DownLoaderUI extends JFrame implements ActionListener{
private JLabel lburl;
private TextField tfurl;
private DownLoader downLoader;
private JLabel lblocation;
private TextField tfloacation;
private JLabel lbcount;
private TextField tfcount;
private int completed=0;
private JButton btnstar;
public JButton btnpause;
public JProgressBar[] bars;
public DownLoaderUI(){
init();
this.setVisible(true);
}
private void init() {
this.setBounds(100,50,800,600);
this.setLayout(null);
lburl=new JLabel("url地址");
lburl.setBounds(0,0,100,30);
this.add(lburl);
tfurl=new TextField("http://localhost:8092/2018-07-01.log");
tfurl.setBounds(0,40,800,30);
this.add(tfurl);
lblocation=new JLabel("保存地址");
lblocation.setBounds(0,80,100,30);
this.add(lblocation);
tfloacation=new TextField("d:/test/down/2018-07-01.log");
tfloacation.setBounds(0,120,800,30);
this.add(tfloacation);
lbcount=new JLabel("線程數(shù)");
lbcount.setBounds(0,160,100,30);
this.add(lbcount);
tfcount=new TextField("3");
tfcount.setBounds(0,200,800,30);
this.add(tfcount);
btnstar=new JButton("開始");
btnstar.setBounds(0,240,100,30);
btnstar.addActionListener(this);
this.add(btnstar);
btnpause=new JButton("暫停");
btnpause.setBounds(150,240,100,30);
btnpause.addActionListener(this);
this.add(btnpause);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(-1);
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
//如果點擊事件為開始
if(source==btnstar){
String url = tfurl.getText();
String location = tfloacation.getText();
int count=Integer.parseInt(tfcount.getText());
downLoader = new DownLoader(url, location, count, this);
addBars(downLoader.getDownLoaderInfos());
downLoader.startDownload();
//如果點擊事件為暫停
}else if(source==btnpause){
//通過調(diào)節(jié)下載線程中的靜態(tài)標記,來調(diào)節(jié)按鈕的名字與開始暫停
DownLoaderThread.pause=!DownLoaderThread.pause;
if(DownLoaderThread.pause){
btnpause.setText("繼續(xù)");
}else{
btnpause.setText("暫停");
}
}
}
private void addBars(List<DownLoaderInfo> list) {
//添加進度條數(shù)組
bars=new JProgressBar[list.size()];
//循環(huán)所有的線程,創(chuàng)建進度條
for (DownLoaderInfo di : list) {
bars[di.getIndex()]=new JProgressBar();
bars[di.getIndex()].setBounds(10,280+(di.getIndex()*50),750,30);
//設置最大值
bars[di.getIndex()].setMaximum(di.getEndPos()-di.getStartPose()+1);
//取出上次進度條所走的進度值
bars[di.getIndex()].setValue(di.getAmount());
this.add(bars[di.getIndex()]);
}
this.repaint();
}
public void updataBars(int index, int len) {
//更新進度條
bars[index].setValue(bars[index].getValue()+len);
synchronized (this){
//如果一個進度條的值大于等于它的最大值了,就是下完了
if(bars[index].getValue()>=bars[index].getMaximum()){
completed++;
//如果進度條的數(shù)量等于已下載的數(shù)量說明全下完了,就可以刪除進度條了
if(bars.length==completed){
for (JProgressBar bar : bars) {
this.remove(bar);
}
this.repaint();
completed=0;
bars=null;
downLoader.prop=null;
//下完之后需要關閉進程
BackWriteThread.stop=true;
//下載完成后刪除文件
downLoader.deleteMetaFile();
}
}
}
}
}
主入口:
package DownLoaderItem;
public class Mainx {
public static void main(String[] args) {
new DownLoaderUI();
}
}
下載器類:
package DownLoaderItem;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DownLoader {
private String url;
private String location;
private int count;
//傳遞prop,把下載進度寫入到prop中
public Properties prop;
//把下載信息組成集合
public List<DownLoaderInfo> getDownLoaderInfos() {
return downLoaderInfos;
}
public void setDownLoaderInfos(List<DownLoaderInfo> downLoaderInfos) {
this.downLoaderInfos = downLoaderInfos;
}
private DownLoaderUI ui;
public List<DownLoaderInfo> downLoaderInfos;
public DownLoader(String url, String location, int count, DownLoaderUI ui) {
this.url = url;
this.location = location;
this.count = count;
this.ui = ui;
initDownloaderInfos();
}
public void startDownload(){
for (DownLoaderInfo di : downLoaderInfos) {
new DownLoaderThread(di,ui,this.prop).start();
}
//起新線程寫入后臺
new BackWriteThread(location,prop).start();
}
private void initDownloaderInfos() {
downLoaderInfos=new ArrayList<>();
//如果是第一次下載
if(!isFirst()){
int blockSize=getLen()/count;
for (int i=0;i<count;i++){
int startPos=i*blockSize;
int endPos=0;
if(i==count-1){
endPos=getLen()-1;
}else {
endPos=(i+1)*blockSize-1;
}
DownLoaderInfo d = new DownLoaderInfo(url, location, startPos, endPos, i, 0);
//把下載信息添加進集合
downLoaderInfos.add(d);
}
//首次下載后把元數(shù)據(jù)創(chuàng)建出來,并寫入到文件
creatMetaDate(downLoaderInfos);
//如果不是首次下載
}else {
try {
File f = new File(location + ".meta");
prop = new Properties();
FileInputStream fis = new FileInputStream(f);
prop.load(fis);
//取出線程數(shù)
int count = Integer.parseInt(prop.getProperty("thread.count"));
for (int i=0;i<count;i++){
//循環(huán)所有線程,取出重要數(shù)據(jù)
int startPos = Integer.parseInt(prop.getProperty("thread."+i+".startPos"));
int endPos = Integer.parseInt(prop.getProperty("thread."+i+".endPos"));
int amount = Integer.parseInt(prop.getProperty("thread."+i+".amount"));
DownLoaderInfo d = new DownLoaderInfo(url, location, startPos, endPos, i, amount);
downLoaderInfos.add(d);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
private void creatMetaDate(List<DownLoaderInfo> list) {
try {
File f = new File(location + ".meta");
prop = new Properties();
prop.setProperty("thread.count",list.size()+"");
//循環(huán)線程,把重要數(shù)據(jù)寫入到元數(shù)據(jù)文件
for (DownLoaderInfo di : list) {
prop.setProperty("thread."+di.getIndex()+".startPos",di.getStartPose()+"");
prop.setProperty("thread."+di.getIndex()+".endPos",di.getEndPos()+"");
prop.setProperty("thread."+di.getIndex()+".amount",di.getAmount()+"");
}
FileOutputStream fos = new FileOutputStream(f);
prop.store(fos,"xxx");
fos.close();
}catch (Exception e){
e.printStackTrace();
}
}
public boolean isFirst(){
return new File(location).exists();
}
//獲得url,與下載文件的長度
public int getLen(){
try {
URL u = new URL(this.url);
HttpURLConnection conn= (HttpURLConnection) u.openConnection();
int len = conn.getContentLength();
conn.disconnect();
return len;
}catch (Exception e){
e.printStackTrace();
}
return -1;
}
//刪除元數(shù)據(jù)文件
public void deleteMetaFile(){
File f = new File(location + ".meta");
while (!f.delete()){
}
}
}
下載線程類:
package DownLoaderItem;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;
public class DownLoaderThread extends Thread {
private DownLoaderInfo info;
private DownLoaderUI ui;
public static boolean pause=false;
private Properties prop;
public DownLoaderThread(DownLoaderInfo info, DownLoaderUI ui,Properties prop) {
this.info = info;
this.ui = ui;
this.prop=prop;
}
@Override
public void run() {
try {
URL u = new URL(info.getUrl());
HttpURLConnection conn= (HttpURLConnection) u.openConnection();
//設置下載偏移量
conn.setRequestProperty("Range","bytes="+(info.getStartPose()+info.getAmount())+"-"+info.getEndPos());
InputStream in = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile(info.getLocation(), "rw");
//取得下載偏移量
raf.seek(info.getStartPose()+info.getEndPos());
byte[] buf=new byte[1024];
int len=0;
while((len=in.read(buf))!=-1){
//如果標記為為true就暫停
while(pause){
Thread.sleep(1000);
}
raf.write(buf,0,len);
//更新下載進度到prop線程
updataAmount(info.getIndex(),len);
//更新進度條
ui.updataBars(info.getIndex(),len);
Thread.sleep(1);
}
raf.close();
in.close();
conn.disconnect();
}catch (Exception e){
e.printStackTrace();
}
}
//更新amount到prop
private void updataAmount(int index, int len) {
int amount = Integer.parseInt(prop.getProperty("thread."+index+".amount"));
prop.setProperty("thread."+index+".amount",(amount+len)+"");
}
}
封裝下載信息類:
package DownLoaderItem;
public class DownLoaderInfo {
private String url;
private String location;
private int startPose;
private int endPos;
private int index;
public DownLoaderInfo(String url, String location, int startPose, int endPos,int index) {
this.url = url;
this.location = location;
this.startPose = startPose;
this.endPos = endPos;
this.index=index;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public int getStartPose() {
return startPose;
}
public void setStartPose(int startPose) {
this.startPose = startPose;
}
public int getEndPos() {
return endPos;
}
public void setEndPos(int endPos) {
this.endPos = endPos;
}
}
后臺分線程寫入文件類:
package DownLoaderItem;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;
public class BackWriteThread extends Thread {
private String location;
private Properties prop;
public static boolean stop=false;
public BackWriteThread(String location, Properties prop) {
this.location = location;
this.prop = prop;
this.setDaemon(true);
}
@Override
public void run() {
//把最新的進度通過分線程寫到文件中
File f = new File(location + ".meta");
try {
while(f.exists() && prop!=null) {
if(stop){
return;
}
FileOutputStream fos = new FileOutputStream(f);
prop.store(fos, "xxx");
fos.close();
Thread.sleep(1000);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
本文題目:java多線程下載
文章網(wǎng)址:http://www.rwnh.cn/article12/pgcjgc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、搜索引擎優(yōu)化、網(wǎng)站維護、標簽優(yōu)化、云服務器、網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)