java多线程下载
类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给弄掉了,现在给加上去了.