一:前言
多线程下载文件,可能有的同学没有过多的听说过,但是断点下载肯定是听过的,也就是说像讯雷,哪怕你把电脑重启了,讯雷重新启动后也会接着原来的地方下载,那么这是怎么做到的呢?
二:代码示例
直接给出代码,
2.1、经典代码
两行经典的代码分别为:
//设置下载的开始及结束位置 conn.setRequestProperty("Range", "bytes="+start+"-"+end+"");
//设置读写的起点位置 RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw"); raf.seek(start);
2.2、完整代码:
import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; public class Demo { /** * 下载线程数量<br> * 我用5个线程下载用了37秒,用1个线程下载用了45秒 */ private static int num = 5; public static void main(String[] args) { threadDown(); } public final static void threadDown() { try { URL url = new URL("http://dldir1.qq.com/qqfile/qq/QQ8.2/17724/QQ8.2.exe"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); int size = conn.getContentLength(); // 每个纯种下载该大小 int block = size / num; // 这个类支持对于文件的随机访问,第一个参数是文件名,第二个是访问模式,rw代表读写 RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw"); // 在本地创建一个空文件,大小与服务器的文件保持一致 raf.setLength(size); raf.close(); // 定义一个开始下载的位置,结束下载的位置 int start; int end; for (int i = 0; i < num; i++) { start = i * block; if (num == i + 1) { end = size; } else { end = block * (i + 1); } System.out.println("开始:" + start + ", 结束:" + end); ThreadDown down = new ThreadDown(start,end); down.start(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } class ThreadDown extends Thread{ private int start; private int end; public ThreadDown(int start,int end){ this.start = start; this.end = end; } public void run() { long startTime = new Date().getTime(); String name = Thread.currentThread().getName(); try { System.out.println(name + ":启动"); URL url = new URL("http://dldir1.qq.com/qqfile/qq/QQ8.2/17724/QQ8.2.exe"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //这里也是重点,设置了请求的开始字节与结束字节 conn.setRequestProperty("Range", "bytes="+start+"-"+end+""); InputStream in = conn.getInputStream(); RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw"); //设置读写的起点位置,这里是重点 raf.seek(start); byte[] buf = new byte[1024]; int len = 0; while((len=in.read(buf))!= -1){ raf.write(buf, 0, len); } in.close(); raf.close(); long endTime = new Date().getTime(); long useTime = (endTime - startTime) / 1000; System.out.println(name + "下载完成,共耗时:" + useTime + "秒"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
三:断点下载
想来看过了上面的代码,断点下载的原理大家肯定也是知道了,同样的也是采用
//设置下载的开始及结束位置 conn.setRequestProperty("Range", "bytes="+start+"-"+end+"");
//设置读写的起点位置 RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw"); raf.seek(start);
时间: 2024-10-22 19:36:17