多线程下载文件的实现
package cn.itcast.download; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class testDownlaod { public static final String path="http://192.168.1.106:8080/youdao.exe"; public static void main(String[]args) throws Exception{ URL url=new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1)"); int code=conn.getResponseCode(); if(code==200){ int len=conn.getContentLength(); RandomAccessFile file=new RandomAccessFile("D://baiduyundownload/"+getFileName(path),"rwd"); //1.设置本地文件大小跟服务器的文件大小一致 file.setLength(len); //2.假设开启3个线程 int threadnumber=3; int blocksize=len/threadnumber; /** * 线程的起始位置分别为 * thread1 0~blocksize * thread2 1*blocksize~2*blocksize * thread3 2*blocksize~文件末尾 */ for(int i=0;i<threadnumber;i++){ int startposition=i*blocksize; int endposition=(i+1)*blocksize; if(i==(threadnumber-1)){ //最后一个线程 endposition=len; } DownLoadTask task = new DownLoadTask(i,path,startposition,endposition); task.start(); } } } public static String getFileName(String path) { // TODO Auto-generated method stub int start=path.lastIndexOf("/")+1; return path.substring(start,path.length()); } } class DownLoadTask extends Thread{ public static final String path="http://192.168.1.106:8080/youdao.exe"; int threadid; String filepath; int startposition; int endposition; public DownLoadTask(int threadid,String filepath,int startposition,int endposition){ this.threadid=threadid; this.filepath=filepath; this.startposition=startposition; this.endposition=endposition; } @Override public void run() { // TODO Auto-generated method stub try { URL url=new URL(filepath); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setRequestProperty("Range", "bytes="+startposition+endposition); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1)"); InputStream is=conn.getInputStream(); RandomAccessFile file=new RandomAccessFile(getFileName(path),"rwd"); //设置数据从文件哪个位置开始写 file.seek(startposition); byte[]buffer=new byte[1024]; int len=0; //rwd 代表当前读到的服务器数据的位置,同时这个值已经存储的文件位置 while((len=is.read(buffer))!=-1){ file.write(buffer,0,len); } file.close(); System.out.println("线程" + threadid + "下载完毕"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } super.run(); } public static String getFileName(String path) { int start = path.lastIndexOf("/") + 1; return path.substring(start, path.length()); } }
基本原理:利用URLConnection获取要下载文件的长度、头部等相关信息,并设置响应的头部信息。并且通过URLConnection获取输入流,将文件分成指定的块,每一块单独开辟一个线程完成数据的读取、写入。通过输入流读取下载文件的信息,然后将读取的信息用RandomAccessFile随机写入到本地文件中。同时,每个线程写入的数据都文件指针也就是写入数据的长度,需要保存在一个临时文件中。这样当本次下载没有完成的时候,下次下载的时候就从这个文件中读取上一次下载的文件长度,然后继续接着上一次的位置开始下载。并且将本次下载的长度写入到这个文件中。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。