zoukankan      html  css  js  c++  java
  • Java多线程下载

    我们可以使用多线程进行下载,这样可以提高下载的效率。这个在JavaSE和android系统中均适用。

    效果:

    附代码如下:

      1 import java.io.InputStream;
      2 import java.io.RandomAccessFile;
      3 import java.net.HttpURLConnection;
      4 import java.net.URL;
      5 
      6 /**
      7  * 多线程下载示例
      8  * @author YUANYUAN
      9  *
     10  */
     11 public class Demo {
     12     //下载所使用的线程数
     13     private static int threadCount=3;
     14 
     15     public static void main(String[] args) throws Exception{
     16         //请求服务器的路径
     17         String path="http://192.168.2.114:8080/sqlite.exe";
     18         //构造URL地址
     19         URL url=new URL(path);
     20         //打开连接
     21         HttpURLConnection conn=(HttpURLConnection) url.openConnection();
     22         //设置请求超时的时间
     23         conn.setConnectTimeout(5000);
     24         //设置请求方式
     25         conn.setRequestMethod("GET");
     26         //获取相应码
     27         int code=conn.getResponseCode();
     28         if (code==200) {//请求成功
     29             //获取请求数据的长度
     30             int length=conn.getContentLength();
     31             //在客户端创建一个跟服务器文件大小相同的临时文件
     32             RandomAccessFile raf=new RandomAccessFile("setup.exe", "rwd");
     33             //指定临时文件的长度
     34             raf.setLength(length);
     35             raf.close();
     36             //假设3个线程去下载资源
     37             //平均每一个线程要下载的文件的大小
     38             int blockSize=length/threadCount;
     39             for (int threadId = 1; threadId <= threadCount; threadId++) {
     40                 //当前线程下载数据的开始位置
     41                 int startIndex=blockSize*(threadId-1);
     42                 //当前线程下载数据的结束位置
     43                 int endIndex=blockSize*threadId-1;
     44                 //确定最后一个线程要下载数据的最大位置
     45                 if (threadId==threadCount) {
     46                     endIndex=length;
     47                 }
     48                 //显示下载数据的区间
     49                 System.out.println("线程【"+threadId+"】开始下载:"+startIndex+"---->"+endIndex);
     50                 //开启下载的子线程
     51                 new DownloadThread(path, threadId, startIndex, endIndex).start();
     52             }
     53             
     54         }else{//请求失败
     55             System.out.println("服务器异常,下载失败!");
     56         }
     57     }
     58     
     59     /**
     60      * 下载文件的子线程 每一个文件都下载对应的数据
     61      * @author Administrator
     62      *
     63      */
     64     public static class DownloadThread extends Thread{
     65         private String path;
     66         private int threadId;
     67         private int startIndex;
     68         private int endIndex;
     69         
     70         /**
     71          * 构造方法
     72          * @param path 下载文件的路径
     73          * @param threadId 下载文件的线程
     74          * @param startIndex 下载文件开始的位置
     75          * @param endIndex 下载文件结束的位置
     76          */
     77         public DownloadThread(String path, int threadId, int startIndex,
     78                 int endIndex) {
     79             this.path = path;
     80             this.threadId = threadId;
     81             this.startIndex = startIndex;
     82             this.endIndex = endIndex;
     83         }
     84 
     85 
     86 
     87         @Override
     88         public void run() {
     89             //构造URL地址
     90             try {
     91                 URL url = new URL(path);
     92                 HttpURLConnection conn=(HttpURLConnection) url.openConnection();
     93                 conn.setConnectTimeout(5000);
     94                 conn.setRequestMethod("GET");
     95                 //设置请求属性,请求部分资源
     96                 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
     97                 int code=conn.getResponseCode();
     98                 if (code==206) {//下载部分资源,正常返回的状态码为206
     99                     InputStream is=conn.getInputStream();//已经设置了请求的位置,所以返回的是对应的部分资源
    100                     //构建随机访问文件
    101                     RandomAccessFile raf=new RandomAccessFile("setup.exe", "rwd");
    102                     //设置 每一个线程随机写文件开始的位置
    103                     raf.seek(startIndex);
    104                     //开始写文件
    105                     int len=0;
    106                     byte[] buffer=new byte[1024];
    107                     while((len=is.read(buffer))!=-1){//读取输入流
    108                         raf.write(buffer,0,len);//写文件
    109                     }
    110                     is.close();
    111                     raf.close();
    112                     //提示下载完毕
    113                     System.out.println("线程【"+threadId+"】下载完毕");
    114                 }
    115             } catch (Exception e) {
    116                 e.printStackTrace();
    117                 System.out.println("线程【"+threadId+"】下载出现异常!!");
    118             }
    119             
    120         }
    121     }
    122 }
  • 相关阅读:
    socket实现一个简单的echo服务
    Netty实现丢弃服务协议(Netty4.X学习一)
    大型情感剧集Selenium:8_selenium网页截图的四种方法
    python原类、类的创建过程与方法
    Flask使用bootstrap为HttpServer添加上传文件功能
    充满含金量的一场云原生Meetup,入场券免费发送中……
    Hadoop伪分布式集群的安装部署
    从缓冲池命中率角度判断自己的MYSQL数据库是否需要扩容内存
    MySQL分区表概述
    如何防止mysql数据库被勒索
  • 原文地址:https://www.cnblogs.com/javayuan/p/4946123.html
Copyright © 2011-2022 走看看