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

📄 download.java

📁 在主函数中建立一个服务器套接字端口
💻 JAVA
字号:
import java.io.*;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;


public class Download extends Frame 
 
 { 
   
   private File fileOut;
    
   private URL url;
    
   private long fileLength;
   
   private int ThreadNum;           //初始化线程数
   //private Label l1 = new Label("请输入下载地址:");   //创建标签L1
   
   private TextField tf1 = new TextField();   //创建文本域tf1长度为30
   //private Label l2 = new Label("请输入需要的线程:");  //创建标签L2
   
   private TextField tf2 = new TextField();      //创建tf2 输入线程
   private TextField tf3 = new TextField();    //创建tf3 保存地址
   static TextArea ta = new TextArea();       //创建文本区ta
   
   private Button b = new Button();
   //private Panel p = new Panel();


   public Download() 
   
   {
   	
   	Panel pSave=new Panel();
   	pSave.add(new Label("请输入保存地址")); 
   	pSave.add(tf3=new TextField(25));
   	//tf1.setColumns(50); 
  
  
    
    Panel pDown=new Panel(); 
    pDown.add(new Label("请输入下载地址")); 
    pDown.add(tf1=new TextField(25)); 
    //tf2.setColumns(50); 
     
    
    Panel pXian=new Panel(); 
    pXian.add(new Label("请输入所需线程")); 
    pXian.add(tf2=new TextField(5)); 
    //tf3.setColumns(10);
     
     
    Panel pLeft=new Panel(); 
    pLeft.setLayout(new GridLayout(3,1));
    pLeft.add(pDown); 
    pLeft.add(pSave);
    pLeft.add(pXian);
   
    Panel pCenter=new Panel(); 
    ta=new TextArea(80,30); 
    pCenter.setLayout(new BorderLayout()); 
    pCenter.add(pLeft,BorderLayout.WEST); 
    pCenter.add(ta,BorderLayout.EAST); 
    Panel pBtn=new Panel();  
    pBtn.add(b=new Button("下载")); //创建按钮
    pCenter.add(pBtn,BorderLayout.SOUTH); 
    
    this.add(pCenter);
   	this.setTitle("多线程下载软件");
   	this.setSize(600,300);
   	this.setLocation(280,280);
   	pLeft.setBackground(Color.white); //设定面板的背景颜色为白色
	pBtn.setBackground(Color.white);
	pCenter.setBackground(Color.white);
    ta.append("下载过程显示"+"\n\n"); 
	this.setVisible(true);

	
	//给b注册监听器
	b.addActionListener(new ActionListener()            
	
	{            
      public void actionPerformed(ActionEvent e) 
      {
      	
      try{
      	
            	
         String str = tf1.getText();
         ThreadNum = Integer.valueOf(tf2.getText());  //把字符串变量转换为整形变量
         String str2 =tf3.getText();
         String info=new String();
         
         long[] startPos;  //设置起始位置
         long[] endPos;    //设置结束位置
         long[] xPos;      //设置读取字节
         int i ,y;
         //初始化
         startPos=new long[ThreadNum];   
         endPos=new long[ThreadNum];
         xPos=new long[ThreadNum];
         System.out.println(str);
         System.out.println("正在链接URL");
         ta.append("正在链接URL\n");
      
         //构造URL链接
         /*在构建了URL后,调用它的函数openConnection()返回一个HttpURLConnection实例,
         用getContentLength实现获取远程文件的长度,
         然后调用getResponseCode()返回HTTP的响应状态码,
         状态小于400就表示正常,返回大于400的,比如401就表示服务器
         不正常了,返回小于零的,比如-1则表示无法获知文件大小。*/
         url=new URL(str);      
         HttpURLConnection urlcon=(HttpURLConnection)url.openConnection(); 
         fileLength=urlcon.getContentLength(); 
         printMIME(urlcon);       //打印信息 
         System.out.println("下载文件大小为"+fileLength/1024+"K");
         ta.append("下载文件大小为"+fileLength/1024+"K"+"\n\n"); 
        
         //设置连接信息
         
        if(urlcon.getResponseCode()>=400)
        { 
          System.out.println("服务器响应错误"); 
          System.exit(-1); 
        } 
        
        if(fileLength<=0) 
          System.out.println("无法获知文件大小");
       
        else
        
        {
               //设置线程显示
               
          long threadLength=fileLength/ThreadNum;
                
          for(i=0;i<ThreadNum;i++)
          { 
            startPos[i]=threadLength*i;  
                  
            xPos[i]=threadLength; 
                 
            xPos[ThreadNum-1]=fileLength-threadLength*(ThreadNum-1);  //多线程正常读取字节
                  
            endPos[i]=threadLength*i+xPos[i];
                 
            y=i+1;
                 
            System.out.println("第"+y+"线程从第"+startPos[i]+"个字节开始读取"+xPos[i]+"个字节");
          
            ta.append("第"+y+"线程从第"+startPos[i]+"个字节开始读取"+xPos[i]+"个字节"+"\n");
               
            System.out.println("线程:"+y+"下载范围:"+startPos[i]+"--"+endPos[i]);
          
            ta.append("线程:"+y+"下载范围:"+startPos[i]+"--"+endPos[i]+"\n");
                 
            //获取URL,转变成字符串赋值给trueurl
            
            String trueurl=urlcon.getURL().toString(); 
        
            //获取文件名,substring截取'/'后的
           
            String filename=trueurl.substring(trueurl.lastIndexOf('/')+1); 
           //设置保存位置
            fileOut=new File(str2,filename); 
            
         } 
       }
       }
        catch(IOException ie)
        { 
             System.err.println(ie); 
         } 
         
   init();
          }
         }
       );
           
    //对窗口监听,使其可以正常关闭
	this.addWindowListener(new WindowAdapter()
	{ 
        public void windowClosing(WindowEvent e)
        { 
             System.exit(0); 
          } 
        } 
        );
    
      }   
   private void init()
      { 
        Threads [] down = new Threads[ThreadNum]; //启动一组子线程
   try 
      { 
      
      for(int i=0;i<ThreadNum;i++)
      { 
         RandomAccessFile randOut=new RandomAccessFile(fileOut,"rw"); 
         randOut.setLength(fileLength); 
         long threadLength=fileLength/ThreadNum; //每个线程长度
         randOut.seek(threadLength*i);  //用于移动文件指针到指定的位置
         down[i]=new Threads(url,randOut,threadLength,i+1); //引用线程类对象
         down[i].setPriority(10); //设置优先级为10
         down[i].start(); //启动新创建的线程
      } 
      
       //循环判断是否下载完毕
    
      boolean flag=true; 
      while (flag) 
      {        
       //等待下载过程结束
       Threads.sleep(1000); //调用Thread类的sleep()方法使线程在指定的时间内处于休眠,设为休眠1秒 
       flag = false; 
       for (int i = 0; i < ThreadNum; i++)   //检测是否每条线程都已经完成
       if (!down[i].isFinished()) 
        { 
          flag = true; 
          break; 
        } 
      }// end while 
  
  
      System.out.println("文件下载完毕,保存在"+fileOut.getPath() );
      ta.append("文件下载完毕,保存在"+fileOut.getPath()+"\n\n");
      } 
         
        catch (FileNotFoundException e) 
        { 
         System.err.println(e); 
         e.printStackTrace(); 
        }
    
        catch(IOException e)
        { 
         System.err.println(e); 
         e.printStackTrace(); 
        } 
   
        catch (InterruptedException e) //抛出异常,唤醒睡眠
        { 
         System.err.println(e); 
        } 

  } 

  /*显示相关信息
  这里调用了getHeaderFieldKey方法,返回第i个文件头的索引键值。
然后以返回的mine为参数调用了getHeaderField方法,返回第i个
文件头的实际值,也就是文件长度。调用MIME显示下载对象的相关信息。*/

  private void printMIME(HttpURLConnection http)
   { 
     for(int i=0;;i++)
   { 
     String mine=http.getHeaderField(i); 
     if(mine==null) 
     return; 
     System.out.println(http.getHeaderFieldKey(i)+":"+mine);
     ta.append(http.getHeaderFieldKey(i)+":"+mine);
     ta.append("\n\n");
    } 
   }     

  public static void main(String[] args) 
   { 
         Download app=new Download();   
   }
    

  }    //结束


//线程类

class Threads extends Thread

  { 
    private InputStream randIn; 
    private RandomAccessFile randOut; 
    private URL url; 
    private long threadLength; 
    private int ThreadId;          //子线程ID
    private boolean done=false;   //文件传输完成标志

   public Threads(URL url,RandomAccessFile out,long threadLength,int ThreadId)
   
   { 
     this.url=url; 
     this.randOut=out; 
     this.threadLength=threadLength; 
     this.ThreadId=ThreadId; 
   } 
   
   
 public void run()
 
 { 
   try
      { 
      
       HttpURLConnection http=(HttpURLConnection)url.openConnection(); 
       //设置开始位置
       http.setRequestProperty("Range","bytes="+threadLength*(ThreadId-1)+"-"); 
       randIn=http.getInputStream(); 
       //请求传输开始的位置

       }
       
   catch(IOException e)
   
       { 
          System.err.println(e); 
        } 



   byte [] buffer=new byte[1024]; 
   int offset;
   long localSize=0; 
   System.out.println("线程"+ThreadId+"开始下载"); 
   Download.ta.append("线程"+ThreadId+"开始下载\n");
   try 
      { 
      while ((offset = randIn.read(buffer))>0&&localSize<=threadLength) 
      { 
         randOut.write(buffer,0,offset); 
      
         localSize+=offset; //下一次开始写的位置
      } 
      
      randOut.close(); 
      randIn.close(); 
      done=true; 
      System.out.println("线程"+ThreadId+"完成下载"); 
      Download.ta.append("线程"+ThreadId+"完成下载\n");
   
      
      this.interrupt(); 
      
      } 
   
   catch(Exception e)
   
      { 
         System.err.println(e); 
      } 
} 

   public boolean isFinished()
  
     { 
       return done; 
     } 
}

⌨️ 快捷键说明

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