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给弄掉了,现在给加上去了.

 

posted @ 2013-06-13 00:57  廖世勇  阅读(218)  评论(0编辑  收藏  举报