使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放10毫秒的水要多。
- XML/HTML 代码复制内容到剪贴板
- package cn.mzba.download;
- import java.io.File;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class MulThreadDownloader {
- /**
- * 1、首先获取网络上的内容,然后获取文件的长度,标题。 然后在本地上生成一个同样大小并且同名的文件。 2、执行线程
- * 3、线程首先定义一个随机输入流,用来下载文件同步写入本地文件 设置Range从指定的开始位置-结束位置下载文件。
- * 4、获取服务器返回的输入流写入文件。
- *
- */
- public static void main(String[] args) throws Exception {
- String path = "http://www.wo...56c.jpg";
- new MulThreadDownloader().download(path, 3);
- System.in.read();
- }
- public void download(String path, int threadsize) throws Exception {
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5 * 1000);
- int length = conn.getContentLength(); // 获取文件长度
- File localfile = new File(getFileName(path));
- RandomAccessFile file = new RandomAccessFile(localfile, "rwd");
- file.setLength(length);
- file.close();
- // 计算每条线程下载的数据长度
- int block = length % threadsize == 0 ? length / threadsize : length
- / threadsize + 1;
- for (int i = 0; i < threadsize; i++) {
- new DownLoadThread(i, url, block, localfile).start();
- }
- }
- private final class DownLoadThread extends Thread {
- private int threadid;
- private URL url;
- private int block;
- private File localfile;
- public DownLoadThread(int threadid, URL url, int block, File localfile) {
- this.threadid = threadid;
- this.block = block;
- this.url = url;
- this.localfile = localfile;
- }
- @Override
- public void run() {
- int startposition = threadid * block; // 从网络文件的什么位置开始下载数据
- int endposition = startposition + block - 1; // 下载到文件的什么位置结束
- RandomAccessFile file;
- try {
- file = new RandomAccessFile(localfile, "rwd");
- file.seek(startposition);
- HttpURLConnection conn = (HttpURLConnection) url
- .openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5 * 1000);
- conn.setRequestProperty("Range", "bytes=" + startposition + "-"
- + endposition);
- InputStream is = conn.getInputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = is.read(buffer)) != -1) {
- file.write(buffer, 0, len);
- }
- is.close();
- file.close();
- System.out.println("线程id" + threadid + "已经下载完成");
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- super.run();
- }
- }
- public static String getFileName(String path) {
- return path.substring(path.lastIndexOf("/") + 1);
- }
- }