⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlframe.java~5~

📁 自己编写的一个在Java中通过http协议多线程下载的一个程序例子。通过HTTP请求先得到文件长度
💻 JAVA~5~
字号:
//package MTdownload;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.io.*;

public class DLFrame extends JFrame{
	private JPanel contentPane;
	private TextField textField1 = new TextField();//输入url和端口
	private TextField textField2 = new TextField();//输入保存路径
	private Button button = new Button();//启动下载活动的按钮
	private Label label1 = new Label();//提示输入下载的url
	private Label label2 = new Label();//提示输入保存路径和文件名
    private TextArea textArea = new TextArea();//输出用户交互的提示信息
	private String dlURL = new String();//要下载的目标文件的完整url
	private String saveFileAs = new String();//文件保存的路径和名称

	public DLFrame() {
		enableEvents(AWTEvent.WINDOW_EVENT_MASK);
		try{
			toInit();
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

	private void toInit() throws Exception{//初始化窗体
		contentPane = (JPanel) this.getContentPane();
		contentPane.setLayout(null);
		this.setSize(new Dimension(380,320));
		this.setTitle("多线程下载");
		textField1.setBounds(new Rectangle(150,200,200,20));
		textField1.setText("http://localhost:8080/try.zip");
		textField2.setBounds(new Rectangle(150,240,150,20));
		textField2.setText("f:\\rar.zip");
		label1.setBounds(new Rectangle(20,200,120,20));
		label1.setText("下载的目标文件为:");
		label2.setBounds(new Rectangle(20,240,120,20));
		label2.setText("下载的文件另存为:");
		button.setBounds(new Rectangle(310,240,40,20));
		button.setLabel("下载");
		button.addActionListener(new java.awt.event.ActionListener() {
      		public void actionPerformed(ActionEvent ee) {
        		button_actionPerformed(ee);
      		}
    	});
    	textArea.setBounds(new Rectangle(20,20,330,170));
    	textArea.setEditable(false);
    	contentPane.add(textField1,null);
    	contentPane.add(textField2,null);
    	contentPane.add(label1,null);
    	contentPane.add(label2,null);
    	contentPane.add(button,null);
    	contentPane.add(textArea,null);

    	dlURL = "http://localhost:8080/try.zip";//默认的下载目标
    	saveFileAs = "f:\\rar.zip";//默认的存储位置和名字
	}

	protected void processWindowEvent(WindowEvent e){
		super.processWindowEvent(e);
		if (e.getID() == WindowEvent.WINDOW_CLOSING){
			System.exit(0);
		}
	}

	void button_actionPerformed(ActionEvent ee){//启动下载文件的主线程
		try{
			dlURL = textField1.getText();
			saveFileAs = textField2.getText();
			if(dlURL.compareTo("") == 0 && saveFileAs.compareTo("") == 0 ) {
				textArea.setText("请输入要下载的文件和保存文件完整地址\n然后点击下载键重新下载");
			}
			else{
				DownFile fileFetch = new DownFile(dlURL,saveFileAs,1,textArea);
				fileFetch.start();
				textArea.append("\n主线程启动....");
			}
		}
		catch(Exception e){
			e.printStackTrace ();
			textArea.append("\nError0:" + e);
		}
	}
}


class DownFileSplitter extends Thread {
  String dlURL; 										// 定义文件传输时服务器的URL
  long startPos; 									// 分段的开始位置
  long endPos; 									// 分段的结束位置
  int threadID; 									// 子线程ID
  TextArea textArea = new TextArea();
  boolean done = false;						 // 文件传输完成
  boolean stop = false; 							// 文件传输被终止
  RandomAccessFile file;

  public DownFileSplitter(String dlURL,String saveAs,long nStart,long nEnd,int id,TextArea textArea) throws IOException{
    this.dlURL = dlURL;
    this.startPos = nStart;
    this.endPos = nEnd;
    threadID = id;
    this.textArea = textArea;
    file = new RandomAccessFile(saveAs,"rw");
    file.seek(startPos);
  }

  public void run(){
    int readNum;
    while(startPos < endPos && !stop){
      try{
        URL url = new URL(dlURL);
        HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection ();
        String sProperty = "bytes="+startPos+"-";
        httpConnection.setRequestProperty("RANGE",sProperty);//请求传输的开始位置
        System.out.println("线程" + threadID + " 下载文件......请等待" );
        textArea.append("\n线程" + threadID + "下载文件......请等待");
        InputStream input = httpConnection.getInputStream();
        byte[] b = new byte[1024];
        int offset;
        offset = (int)endPos - (int)startPos;
        if(offset>1024) offset = 1024;

        while(startPos < endPos &&(readNum=input.read(b,0,offset))> 0 && !stop){
          //offset = (int)endPos - (int)startPos;
         // if(offset>1024) offset = 1024;
          System.out.println("线程" + threadID +"started " + startPos + " Read: " + readNum);
          file.write(b,0,readNum);
          startPos += readNum;//下一次开始写的位置
        }
        System.out.println("线程 " + threadID + " 下载完毕!!");
        done = true;
        textArea.append("\n线程" + threadID + " 下载完毕!");
        file.close();
      }
      catch(Exception e){
        e.printStackTrace ();
      }
    }
  }

  public void splitterStop(){
    stop = true;
  }
}


class DownFile extends Thread {   // 传输文件线程类
  String dlURL;
  String saveFileAs;
  int nthread;
  String info = new String();
  TextArea textArea = new TextArea();

  long[] position;
  long[] startPos; //开始位置
  long[] endPos; //结束位置
  DownFileSplitter[] downFileSplitter; //子线程对象
  long fileLength; //文件长度
  boolean stop = false; //停止标志
  DataOutputStream output; //输出到文件的输出流

  public DownFile(String sURL,String saveFileAs,int nthread,TextArea textArea) throws IOException{
    this.dlURL = sURL;
    this.saveFileAs = saveFileAs;
    this.nthread = nthread;
    this.textArea = textArea;

    startPos = new long[nthread];//各个线程的开始位置
    endPos = new long[nthread];//各个线程的结束位置
  }

  public void run(){
    info = "目标文件: " + dlURL;
    System.out.println(info);
    textArea.append("\n" + info);
    info = "文件存为: " + saveFileAs;
    System.out.println(info);
    textArea.append("\n" + info);
    info = "\n线程总数: " + nthread;
    System.out.println(info);
    textArea.append("\n" + info);

    try{
        fileLength = getFileSize();
        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]-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);
      		}
           */
           endPos[0]=fileLength;
          }

      downFileSplitter = new DownFileSplitter[startPos.length];//启动一组子线程
      for(int i=0;i<startPos.length;i++){
        downFileSplitter[i] = new DownFileSplitter(dlURL,saveFileAs,startPos[i],endPos[i],i,textArea);
        info = "线程" + i + " 启动";
        textArea.append("\n" + info);
        downFileSplitter[i].start();
        System.out.println(info);

      }

      boolean breakWhile = false;
      while(!stop){//等待整个下下载过程结束
        Thread.sleep(500);
        breakWhile = true;
        for(int i=0;i<startPos.length;i++){//检测每条线程都已经完成则整个下载完成
          if(!downFileSplitter[i].done){
          breakWhile = false;
          break;
        }
      }
      if(breakWhile)
        break;
      }
      System.out.println("文件传输结束!");//文件传输结束
      textArea.append("\n文件传输结束!");
    }
    catch(Exception e){
      e.printStackTrace ();
    }
  }


  public long getFileSize(){//获得文件长度
    int fileLength = -1;
    try{
      URL url = new URL(dlURL);
      HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection ();
      int responseCode=httpConnection.getResponseCode();
      if(responseCode>=400){
        processErrorCode(responseCode);
        return -2; //Web服务器响应错误
      }
      String sHeader;
      for(int i=1;;i++){//查找标识文件长度的文件头,获取文件长度
        sHeader=httpConnection.getHeaderFieldKey(i);
        if(sHeader!=null){
          if(sHeader.equals("Content-Length")){
            fileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader));
            break;
          }
        }
        else
          break;
      }
    }
    catch(IOException e){e.printStackTrace ();}
    catch(Exception e){e.printStackTrace ();}
    return fileLength;
  }

  private void processErrorCode(int nErrorCode){
    System.err.println("Error Code : " + nErrorCode);
  }

  //停止文件传输
  public void siteStop(){
    stop = true;
    for(int i=0;i<startPos.length;i++)
      downFileSplitter[i].splitterStop();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -