我们可以使用多线程进行下载,这样可以提高下载的效率。这个在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 }