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

📄 downfile.java

📁 这是多线程下载的代码
💻 JAVA
字号:
package Tiff;

import java.awt.TextArea;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

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

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

//the second class
	public 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];
	            }
	            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 = new DownFileSplitter[startPos.length];//启动一组子线程数组,起始位置为 downFileSplitter
	      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){//if not done,continue
	          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 + -