视频图片--多线程下载工具
程序员文章站
2022-07-11 11:18:13
还嫌网速慢? 那是因为你没有一个好的下载工具, 多线程下载, 线程个数自己定义, 想多块就多快,一起来看看吧!!! 多线程使用线程计数同步辅助,同步计算多线程个数,如果线程下载超时, 支持重新下载,方便使用. 1.多线程工具类: MutiThreadDownLoad.java 2.封装工具类方法: ......
还嫌网速慢? 那是因为你没有一个好的下载工具, 多线程下载, 线程个数自己定义, 想多块就多快,一起来看看吧!!!
多线程使用线程计数同步辅助,同步计算多线程个数,如果线程下载超时, 支持重新下载,方便使用.
1.多线程工具类: mutithreaddownload.java
import java.io.inputstream; import java.io.randomaccessfile; import java.net.httpurlconnection; import java.net.url; import java.text.simpledateformat; import java.util.date; import java.util.concurrent.countdownlatch; public class mutithreaddownload { // 同时下载的线程数 private int threadcount; // 服务器请求路径 private string serverpath; //记录下载完成的次数 public static int number_thread=50; //本地路径 private string localpath; //线程计数同步辅助 private countdownlatch latch; public mutithreaddownload(int threadcount, string serverpath, string localpath, countdownlatch latch) { this.number_thread=threadcount; this.threadcount = threadcount; this.serverpath = serverpath; this.localpath = localpath; this.latch = latch; } public boolean executedownload() { try { url url = new url(serverpath); httpurlconnection conn = (httpurlconnection) url.openconnection(); conn.setconnecttimeout(5000); conn.setrequestmethod("get"); int code = conn.getresponsecode(); if (code == 200) { //服务器返回的数据的长度,实际上就是文件的长度,单位是字节 int length = conn.getcontentlength(); system.out.println("文件总长度:" + length + "字节(b)"); if (length == 0) { return false; } randomaccessfile raf = new randomaccessfile(localpath, "rwd"); //指定创建的文件的长度 raf.setlength(length); raf.close(); //分割文件 int blocksize = length / threadcount; for (int threadid = 1; threadid <= threadcount; threadid++) { //第一个线程下载的开始位置 int startindex = (threadid - 1) * blocksize; int endindex = startindex + blocksize - 1; if (threadid == threadcount) { //最后一个线程下载的长度稍微长一点 endindex = length; } system.out.println("线程" + threadid + "下载:" + startindex + "字节~" + endindex + "字节"); new downloadthread(threadid, startindex, endindex).start(); } } } catch (exception e) { e.printstacktrace(); } return true; } /** * 内部类用于实现下载 */ public class downloadthread extends thread { //线程id private int threadid; //下载起始位置 private int startindex; //下载结束位置 private int endindex; public downloadthread(int threadid, int startindex, int endindex) { this.threadid = threadid; this.startindex = startindex; this.endindex = endindex; } @override public void run() { down_time(); } /** * 如果超时,或者下载失败,就使用递归重新下载 */ public void down_time(){ try { system.out.println("线程" + threadid + "正在下载..."); url url = new url(serverpath); httpurlconnection conn = (httpurlconnection) url.openconnection(); conn.setrequestmethod("get"); //请求服务器下载部分的文件的指定位置 conn.setrequestproperty("range", "bytes=" + startindex + "-" + endindex); conn.setconnecttimeout(10000); conn.setreadtimeout(10000); int code = conn.getresponsecode(); system.out.println("线程" + threadid + "请求返回code=" + code); inputstream is = conn.getinputstream();//返回资源 randomaccessfile raf = new randomaccessfile(localpath, "rwd"); //随机写文件的时候从哪个位置开始写 raf.seek(startindex);//定位文件 int len = 0; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { raf.write(buffer, 0, len); } is.close(); raf.close(); number_thread=number_thread-1; system.out.println("线程" + threadid + "下载完毕 "+number_thread); //计数值减一 latch.countdown(); } catch (exception e) { system.out.println(new simpledateformat("yyyy-mm-dd hh:mm:ss aa").format(new date())+":线程 "+threadid + "访问超时,重新下载!!"); down_time(); } } } }
2.封装工具类方法:
public static boolean download(string remoteurl,string localurl){ boolean bd=true; int threadsize = 50; string serverpath = remoteurl; string localpath = localurl; long starttime = system.currenttimemillis(); countdownlatch latch = new countdownlatch(threadsize); mutithreaddownload m = new mutithreaddownload(threadsize, serverpath, localpath, latch); try { boolean x = m.executedownload(); //如果文件的长度等于0,则直接跳过等待,不提示错误 if (x){ latch.await(); }else{ bd=false;//下载失败 } } catch (interruptedexception e) { e.printstacktrace(); } long endtime = system.currenttimemillis(); system.out.println("全部下载结束,共耗时" + (endtime - starttime) / 1000 + "s"); return bd; }
3.使用示例:
string urlss="";//要下载的网络资源路径
string urltt="";//要存放的本地路径
download(urlss,urltt);