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 }
原文地址:https://www.cnblogs.com/javayuan/p/4946123.html