码迷,mamicode.com
首页 > 编程语言 > 详细

多线程实现下载文件

时间:2016-07-19 22:16:46      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

一:需求分析

1:下载远程资源文件,通过多线程下载,达到高效的目的。

2:使用5个线程分别下载文件的不同部分。

 

二:定义成员变量以及初始化变量

 1 // 定义成员变量
 2     private String path; // 远程资源路径
 3     private String targetPath; // 本地存储路径
 4     private DownFileThread[] threads; // 线程list
 5     private int threadNum; // 线程数量
 6     private long length; // 下载的文件大小
 7 
 8     // 构造初始化
 9     public DownloadUtil(String path, String targetPath, int threadNum) {
10         super();
11         this.path = path;
12         this.targetPath = targetPath;
13         this.threads = new DownFileThread[threadNum];
14         this.threadNum = threadNum;
15     }

 

三:多线程下载文件

 

 1 // 多线程下载文件资源
 2     public void download() {
 3         URL url;
 4         try {
 5             url = new URL(path);
 6             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 7             conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
 8             conn.setRequestMethod("GET");
 9             conn.setRequestProperty("connection", "keep-alive");
10             conn.setRequestProperty("accept", "*/*");
11 
12             // 获取远程文件的大小
13             length = conn.getContentLength();
14             conn.disconnect();
15 
16             // 设置本地文件大小
17             RandomAccessFile targetFile = new RandomAccessFile(targetPath, "rw");
18             targetFile.setLength(length);
19 
20             // 每个线程下载大小
21             long avgPart = length / threadNum + 1;
22             // 下载文件
23             for (int i = 0; i < threadNum; i++) {
24                 long startPos = avgPart * i;
25                 RandomAccessFile targetTmp = new RandomAccessFile(targetPath,
26                         "rw");
27                 targetTmp.seek(startPos); // 分段下载
28                 threads[i] = new DownFileThread(startPos, targetTmp, avgPart);
29                 threads[i].start();
30             }
31         } catch (Exception e) {
32             e.printStackTrace();
33         }
34     }

启动多个线程,每个线程下载文件的一部分,并发执行。

 

四:监控文件下载进度

1 // 监控下载进度
2     public double getDownRate() {
3         int currentSize = 0;
4         for (int i = 0; i < threadNum; i++) {
5             currentSize += threads[i].length;
6         }
7         return currentSize * 1.0 / length;
8     }

如果下载的文件比较大,可以使用进度条显示。

 

五:定义线程类

 

 1 // 定义线程类
 2     class DownFileThread extends Thread {
 3         private long startPos;
 4         private RandomAccessFile raf;
 5         private long size;
 6         private long length;
 7 
 8         public DownFileThread(long startPos, RandomAccessFile raf, long size) {
 9             super();
10             this.startPos = startPos;
11             this.raf = raf;
12             this.size = size;
13         }
14 
15         public void run() {
16             URL url;
17             try {
18                 url = new URL(path);
19                 HttpURLConnection conn = (HttpURLConnection) url
20                         .openConnection();
21                 conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
22                 conn.setRequestMethod("GET");
23                 conn.setRequestProperty("connection", "keep-alive");
24                 conn.setRequestProperty("accept", "*/*");
25 
26                 InputStream in = conn.getInputStream();
27                 in.skip(this.startPos);
28                 byte[] buf = new byte[1024];
29                 int hasRead = 0;
30                 while (length < size && (hasRead = in.read(buf)) != -1) {
31                     raf.write(buf, 0, hasRead);
32                     length += hasRead;
33                 }
34                 raf.close();
35                 in.close();
36             } catch (Exception e) {
37                 e.printStackTrace();
38             }
39         }
40     }

 

六:测试多线程下载文件

 1 public static void main(String[] args) {
 2         String path = "http://localhost:8080/healthcare/html/HealthCare.war";
 3         String targetPath = "D:/healthcare.war";
 4         final DownloadUtil download = new DownloadUtil(path, targetPath, 4);
 5         download.download();
 6         // 主线程负责下载文件,在启动一个线程负责监控下载的进度
 7         new Thread(new Runnable() {
 8 
 9             @Override
10             public void run() {
11                 while (download.getDownRate() < 1) {
12                     System.out.println(download.getDownRate());
13                     try {
14                         Thread.sleep(200); // 200毫秒扫描一次
15                     } catch (InterruptedException e) {
16                         e.printStackTrace();
17                     }
18                 }
19             }
20 
21         }).start();
22     }

 

七:全部代码如下

技术分享
  1 /**
  2  * 
  3  */
  4 package com.hlcui.thread;
  5 
  6 import java.io.InputStream;
  7 import java.io.RandomAccessFile;
  8 import java.net.HttpURLConnection;
  9 import java.net.URL;
 10 
 11 /**
 12  * @author Administrator 多线程下载文件
 13  */
 14 public class DownloadUtil {
 15     // 定义成员变量
 16     private String path; // 远程资源路径
 17     private String targetPath; // 本地存储路径
 18     private DownFileThread[] threads; // 线程list
 19     private int threadNum; // 线程数量
 20     private long length; // 下载的文件大小
 21 
 22     // 构造初始化
 23     public DownloadUtil(String path, String targetPath, int threadNum) {
 24         super();
 25         this.path = path;
 26         this.targetPath = targetPath;
 27         this.threads = new DownFileThread[threadNum];
 28         this.threadNum = threadNum;
 29     }
 30 
 31     // 多线程下载文件资源
 32     public void download() {
 33         URL url;
 34         try {
 35             url = new URL(path);
 36             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 37             conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
 38             conn.setRequestMethod("GET");
 39             conn.setRequestProperty("connection", "keep-alive");
 40             conn.setRequestProperty("accept", "*/*");
 41 
 42             // 获取远程文件的大小
 43             length = conn.getContentLength();
 44             conn.disconnect();
 45 
 46             // 设置本地文件大小
 47             RandomAccessFile targetFile = new RandomAccessFile(targetPath, "rw");
 48             targetFile.setLength(length);
 49 
 50             // 每个线程下载大小
 51             long avgPart = length / threadNum + 1;
 52             // 下载文件
 53             for (int i = 0; i < threadNum; i++) {
 54                 long startPos = avgPart * i;
 55                 RandomAccessFile targetTmp = new RandomAccessFile(targetPath,
 56                         "rw");
 57                 targetTmp.seek(startPos); // 分段下载
 58                 threads[i] = new DownFileThread(startPos, targetTmp, avgPart);
 59                 threads[i].start();
 60             }
 61         } catch (Exception e) {
 62             e.printStackTrace();
 63         }
 64     }
 65 
 66     // 监控下载进度
 67     public double getDownRate() {
 68         int currentSize = 0;
 69         for (int i = 0; i < threadNum; i++) {
 70             currentSize += threads[i].length;
 71         }
 72         return currentSize * 1.0 / length;
 73     }
 74 
 75     // 定义线程类
 76     class DownFileThread extends Thread {
 77         private long startPos;
 78         private RandomAccessFile raf;
 79         private long size;
 80         private long length;
 81 
 82         public DownFileThread(long startPos, RandomAccessFile raf, long size) {
 83             super();
 84             this.startPos = startPos;
 85             this.raf = raf;
 86             this.size = size;
 87         }
 88 
 89         public void run() {
 90             URL url;
 91             try {
 92                 url = new URL(path);
 93                 HttpURLConnection conn = (HttpURLConnection) url
 94                         .openConnection();
 95                 conn.setReadTimeout(5 * 1000); // 设置超时时间为5秒
 96                 conn.setRequestMethod("GET");
 97                 conn.setRequestProperty("connection", "keep-alive");
 98                 conn.setRequestProperty("accept", "*/*");
 99 
100                 InputStream in = conn.getInputStream();
101                 in.skip(this.startPos);
102                 byte[] buf = new byte[1024];
103                 int hasRead = 0;
104                 while (length < size && (hasRead = in.read(buf)) != -1) {
105                     raf.write(buf, 0, hasRead);
106                     length += hasRead;
107                 }
108                 raf.close();
109                 in.close();
110             } catch (Exception e) {
111                 e.printStackTrace();
112             }
113         }
114     }
115 
116     // 测试
117     public static void main(String[] args) {
118         String path = "http://localhost:8080/healthcare/html/HealthCare.war";
119         String targetPath = "D:/healthcare.war";
120         final DownloadUtil download = new DownloadUtil(path, targetPath, 4);
121         download.download();
122         // 主线程负责下载文件,在启动一个线程负责监控下载的进度
123         new Thread(new Runnable() {
124 
125             @Override
126             public void run() {
127                 while (download.getDownRate() < 1) {
128                     System.out.println(download.getDownRate());
129                     try {
130                         Thread.sleep(200); // 200毫秒扫描一次
131                     } catch (InterruptedException e) {
132                         e.printStackTrace();
133                     }
134                 }
135             }
136 
137         }).start();
138     }
139 }
View Code

 

 

 

多线程实现下载文件

标签:

原文地址:http://www.cnblogs.com/warrior4236/p/5686404.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!