当前位置:首页 » JAVA技术教程

java多线程下载

2013-06-13 00:57 本站整理 浏览(6)

类DownLoad,main类

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Point;

import java.awt.Rectangle;

import java.awt.TextArea;

import javax.swing.JButton;

import javax.swing.JCheckBox;

import javax.swing.JComboBox;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.JTextField;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.File;

import java.awt.CheckboxGroup;

public class DownLoad extends JFrame implements ActionListener{

/**

* @param args

*/

private JPanel contentPane;

private JPanel progressPane;

private JTextField textField1=new JTextField();

private JTextField textField2=new JTextField();

private JButton button=new JButton();

private JButton open = new JButton("打开");

private JButton stop = new JButton("停止");

private JComboBox nThreadBox;

private JCheckBox proxybutton = new JCheckBox();

private JLabel label1=new JLabel();

private JLabel label2=new JLabel();

private JLabel label3=new JLabel("设置代理 : ");

private JLabel label4=new JLabel("下载进度:");

private JLabel label5=new JLabel("线程数:");

private JTextArea textArea=new JTextArea();

private JProgressBar jProgressBar = newJProgressBar();

private int nTread = 5;

static String host = "";

static String port = "";

DownLoadFile downFile;

public DownLoad(){

contentPane = (JPanel)this.getContentPane();

contentPane.setLayout(null);

this.setSize(new Dimension(380,400));

this.setLocation(100,100);

this.setTitle("多线程下载");

textField1.setBounds(newRectangle(150,200,200,20));

textField1.setText("http://");

textField2.setBounds(newRectangle(150,240,120,20));

textField2.setText("d:\\code.rar");

label1.setBounds(new Rectangle(20,200,120,20));

label1.setText("下载的目标文件为: ");

label2.setBounds(new Rectangle(20,240,120,20));

label2.setText("下载的文件另存为: ");

open.setBounds(280, 240, 60, 20);

open.addActionListener(this);

button.setBounds(new Rectangle(20,280,60,20));

button.setText("下载");

button.addActionListener(this);

stop.setBounds(100, 280, 60, 20);

stop.addActionListener(this);

label3.setBounds(165, 280, 80, 20);

proxybutton.setBounds(225, 280, 20, 20);

proxybutton.addActionListener(this);

nThreadBox= new JComboBox(newString[]{"1","2","3","4","5","6","7","8","9","10"});

label5.setBounds(250, 280, 60, 20);

nThreadBox.setBounds(300, 280, 40, 20);

nThreadBox.addActionListener(this);

contentPane.add(textField1,null);

contentPane.add(textField2,null);

contentPane.add(label1,null);

contentPane.add(label2,null);

contentPane.add(open,null);

contentPane.add(button,null);

contentPane.add(stop,null);

contentPane.add(label3,null);

contentPane.add(proxybutton,null);

contentPane.add(label5);

contentPane.add(nThreadBox);

//contentPane.add(textArea,null);

textArea.setEnabled(false);

textArea.setForeground(Color.black);

JScrollPane scrollPane = newJScrollPane(textArea);

scrollPane.setBounds(newRectangle(20,20,330,170));

contentPane.add(scrollPane,null);

progressPane = new JPanel();

progressPane.setBounds(20, 320,330,100);

//jProgressBar.setsetSize(100, 100);

//label4.setBounds(10, 320, 60, 20);

//jProgressBar.setBounds(70, 320, 140, 20);

// jProgressBar.setSize(100, 40);

progressPane.add(label4,null);

progressPane.add(jProgressBar,null);

contentPane.add(progressPane);

// progressPane.add(stop);

this.setDefaultCloseOperation(EXIT_ON_CLOSE);

// this.pack();

}

public static void main(String[] args) {

// TODO Auto-generated method stub

DownLoad download = new DownLoad();

download.setVisible(true);

}

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

if(e.getSource() == open){

JFileChooser fc=new JFileChooser();

if(fc.showSaveDialog(this)==fc.APPROVE_OPTION){

File f=fc.getSelectedFile() ;

textField2.setText(f.getAbsolutePath()) ;

}

}

if(e.getSource() == button){

//progressPane.add(new JButton("nihao"));

String URL = textField1.getText();

String saveURL = textField2.getText();

if(URL.compareTo("")==0 &&saveURL.compareTo("")==0)

{

textArea.setText("请输入要下载的文件和保存文件完整地址");

}

else

{

try

{

downFile=new DownLoadFile(URL,saveURL,textArea,nTread,jProgressBar);

downFile.start();

textArea.append("主线程启动、、、");

}

catch(Exception ex)

{

ex.printStackTrace();

}

}

}

if(e.getSource() == nThreadBox){

String item = nThreadBox.getSelectedItem().toString();

System.out.println("item is :"+item);

nTread = Integer.parseInt(item);

}

if(e.getSource() == stop){

downFile.stop();

textArea.append("\n 停止下载!!");

}

if(e.getSource() == proxybutton){

if(proxybutton.isSelected()){

//proxybutton.get

textArea.append("\n 代理服务被选择");

Point point=this.getLocation();

int x = this.getHeight()/2+point.x;

int y = this.getWidth()/2+point.y;

ProxyPanel proxypanel=new ProxyPanel(x,y);

/*System.getProperties().put("proxySet","true");

System.getProperties().put("proxyHost",host);

System.getProperties().put("proxyPort",port);*/

}else{

textArea.append("\n 取消代理服务");

System.getProperties().clear();

}

}

}

}

--------------------------------------------------------------------------------------------------------------------------------

类DownLoadFile

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.net.HttpURLConnection;

import java.net.URL;

import javax.swing.JButton;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JTextArea;

import javax.swing.Timer;

public class DownLoadFile extends Thread{

private JPanel progressPane;

private String URL;

private String saveURL;

int nthread;

String info = new String();

JTextArea textArea = new JTextArea();

JProgressBar jProgressBar;

long[] startPos;

long[] endPos;

long fileLength;

LownLoadFileThread[] downFileSplitter;

Timer timer;

public DownLoadFile(String URL, StringsaveURL, JTextArea textArea,

int nthread, JProgressBar jProgressBar) {

this.jProgressBar = jProgressBar;

this.URL = URL;

this.saveURL = saveURL;

this.nthread = nthread;

this.startPos = new long[nthread];

this.endPos = new long[nthread];

this.textArea = textArea;

}

public void run() {

info = "目标文件: " + URL;

textArea.append("\n" + info);

info = "\n 线程总数: " + nthread;

textArea.append("\n" + info);

try {

fileLength = getFileSize(URL);

// System.out.println("fileLength is:"+fileLength);

if (fileLength == -1) {

// System.err.println("不可知的文件长度");

textArea.append("\n 不可知的文件长度!请重试!!");

} else {

if (fileLength == -2) {

// System.err.println("文件无法获取!");

textArea.append("\n 文件无法获取!请重试!!");

} else {

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

startPos[i] = (long) (i * (fileLength /startPos.length));

for (int i = 0; i < endPos.length - 1; i++)

endPos[i] = startPos[i + 1];

endPos[endPos.length - 1] = fileLength;

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

info = "线程:"+ i + "下载范围:" + startPos[i] + "--"

+ endPos[i];

// System.out.println(info);

textArea.append("\n" + info);

}

downFileSplitter = newLownLoadFileThread[startPos.length];

jProgressBar.setMaximum(100);

jProgressBar.setMinimum(0);

// jProgressBar.isStringPainted();

jProgressBar.setStringPainted(true);

jProgressBar.setString("0%");

// progressPane.add(jProgressBar);

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

downFileSplitter[i] = newLownLoadFileThread(URL,

startPos[i], endPos[i], i,textArea,

jProgressBar, saveURL);

info = "线程 " + i + "启动";

textArea.append("\n" + info);

downFileSplitter[i].start();

// System.out.println(info);

}

timer = new Timer(100, new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

// TODO Auto-generated method stub

int readTotal = 0;

boolean finished = true;

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

if(downFileSplitter[i].isAlive())

finished = false;

readTotal += downFileSplitter[i].getReadPos();

//System.out.println("readTotal is :"+readTotal);

}

jProgressBar

.setValue((int) ((long)(readTotal) * 100f /fileLength));

jProgressBar

.setString((int) ((long)(readTotal) * 100f /fileLength)

+"%");

if (finished) {

if ((long) readTotal ==fileLength)

JOptionPane.showMessageDialog(null,

"下载完成!!!");

else

JOptionPane.showMessageDialog(null,

"未能完成下载!!!");

timer.stop();

}

}

});

timer.start();

}

}

} catch (Exception ex) {

}

}

public long getFileSize(String URL) {

int fileLength = -1;

try {

URL url = new URL(URL);

HttpURLConnection httpConnection = (HttpURLConnection) (url

.openConnection());

int responseCode = 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")){

intlength=httpConnection.getContentLength();

textArea.append("\n 文件长度:---"+length);

fileLength = Integer.parseInt(httpConnection

.getHeaderField(sHeader));

textArea.append("\n 可知的文件长度:"+fileLength);

break;

}

} else {

break;

}

}

} catch (Exception ex) {

ex.printStackTrace();

}

return fileLength;

}

}

-------------------------------------------------------------------------------------------------------------------------------

类LownLoadFileThread

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

import javax.swing.JButton;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JTextArea;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

public class LownLoadFileThread extends Thread{

private JProgressBar jProgressBar;

String URL;

long startPos;

long endPos;

int threadID;

JTextArea textArea=new JTextArea();

RandomAccessFile file;

private int readPos = 0;

private int in = 0;

public LownLoadFileThread(String URL,long startPos,longendPos,int id,JTextArea textArea

,JProgressBar jProgressBar,StringsaveURL)throws IOException{

this.jProgressBar = jProgressBar;

this.URL = URL;

this.startPos = startPos;

this.endPos = endPos;

this.threadID = id;

this.textArea = textArea;

file=newRandomAccessFile(saveURL,"rw");

file.seek(startPos);

}

public void run(){

//DownLoad download = new DownLoad();

try{

URL url = new URL(URL);

HttpURLConnectionhttpConnection=(HttpURLConnection)url.openConnection();

String sProperty="bytes="+startPos+"-";

httpConnection.setRequestProperty("RANGE",sProperty);

// System.out.println("线程"+threadID+"下载文件、、、请等待");

textArea.append("\n 线程"+threadID+"下载文件、、、请等待");

InputStreaminput=httpConnection.getInputStream();

byte[] buf=new byte[1024];

int offset;

offset=(int)endPos-(int)startPos;

if(offset>1024)

offset=1024;

while((in =input.read(buf,0,offset))>0 && startPos<endPos)

{ if(((int) endPos -(int) startPos)<1024)

in = (int) endPos - (int) startPos;

/*if(in<1024){

System.out.println("in is:"+in+" -- startpos is "+startPos);

}*/

readPos +=in;

//System.out.println("已读取"+in+"个字节。");

textArea.append("\n 线程"+threadID+" 已读取"+readPos+"个字节, start is :"+startPos+" and end is:"+endPos+"。");

offset =(int) endPos - (int) startPos;

if (offset> 1024)

offset = 1024;

// System.out.println("threadID: "+threadID+" started:"+startPos+" offset: "+offset);

file.write(buf,0,in);

startPos+=in;

}

// System.out.println("线程"+threadID+"下载完毕!!");

textArea.append("\n 线程"+threadID+"下载完毕!!");

file.close();

input.close();

}catch(Exception ex){

}

}

public int getReadPos() {

return readPos;

}

public void setReadPos(int readPos) {

this.readPos = readPos;

}

}

-------------------------------------------------------------------------------------------------------------------------------

类ProxyPanel

import java.awt.Dimension;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

public class ProxyPanel extends JFrameimplements ActionListener {

private String host = "000.000.000.000";

private String port = "0000";

private JLabel label1 = newJLabel("主机:");

private JLabel label2 = newJLabel("端口:");

private JTextField hosttext = newJTextField();

private JTextField porttext = newJTextField();

private JButton button = newJButton("确定");

public ProxyPanel(int x, int y) {

// setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

JPanel panel = new JPanel();

panel.setLayout(null);

label1.setBounds(20, 20, 40, 20);

hosttext.setBounds(60, 20, 140, 20);

panel.add(label1, null);

panel.add(hosttext, null);

hosttext.setText(host);

label2.setBounds(20, 60, 40, 20);

porttext.setBounds(60, 60, 140, 20);

panel.add(label2);

panel.add(porttext);

porttext.setText(port);

button.setBounds(85, 100, 60, 20);

button.addActionListener(this);

panel.add(button);

getContentPane().add(panel);

setSize(new Dimension(240, 160));

setVisible(true);

setLocation(x, y);

}

public String getHost() {

return this.host;

}

public String getPort() {

return this.port;

}

public void actionPerformed(ActionEventarg0) {

// TODO Auto-generated method stub

if (arg0.getSource() == button) {

host = hosttext.getText();

//System.out.println(host);

port = porttext.getText();

//System.out.println(port);

System.getProperties().put("proxySet","true");

System.getProperties().put("proxyHost", host);

System.getProperties().put("proxyPort", port);

this.hide();

this.setDefaultCloseOperation(HIDE_ON_CLOSE);

}

}

}

由于时间原因,很遗憾没有实现断点续传的功能,等以后该功能加上后,再上传.界面可能有点难看,不过你可以用java的look&feel来定制任何好看的界面.

很不好意思,上次把类ProxyPanel给弄掉了,现在给加上去了.