测试类:
public class download_test {
/**
* @param args
*/
// 思路:
//
// 1、基本思路是将文件分段切割、分段传输、分段保存。
//
// 2、分段切割用到HttpUrlConnection对象的setRequestProperty("Range", "bytes=" + start + "-" + end)方法。
//
// 3、分段传输用到HttpUrlConnection对象的getInputStream()方法。
//
// 4、分段保存用到RandomAccessFile的seek(int start)方法。
//
// 5、创建指定长度的线程池,循环创建线程,执行下载操作。
public static void main(String[] args) throws IOException {
String urlLocation = "http://pic17.nipic.com/20111102/3707281_235344313129_2.jpg";
String filename=DownloadFileWithThreadPool.getUrl_filename(urlLocation);
String filePath="./"+filename;
int poolLength=3;
try {
DownloadFileWithThreadPool manager = new DownloadFileWithThreadPool();
manager.getFileWithThreadPool(urlLocation,filePath,poolLength);
System.out.println("success");
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
创建 线程池
执行:threadpool.execute(target)
public class DownloadFileWithThreadPool {
public void getFileWithThreadPool(String urlLocation, String filePath, int poolLength) throws IOException {
// Executor线程池
Executor threadPool = Executors.newFixedThreadPool(poolLength);
long len = getContentLength(urlLocation);
for (int i = 0; i < poolLength; i++) {
long start = i * len / poolLength;
long end = (i + 1) * len / poolLength - 1;
if (i == poolLength - 1) {
end = len;
}
//DownloadWithRange实现runnable接口类,重写run函数
DownloadWithRange download = new DownloadWithRange(urlLocation, filePath, start, end);
threadPool.execute(download); //Executor.execute(Runnalbe)
}
}
public static long getContentLength(String urlLocation) throws IOException {
URL url = null;
if (urlLocation != null) {
url = new URL(urlLocation);
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
long len = conn.getContentLength(); //单位byte
// System.out.println("文件大小:" + len + " bytes");
return len;
}
public static String getUrl_filename(String urlLocation) throws IOException {
URL url = null;
if (urlLocation != null) {
url = new URL(urlLocation);
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
URL absUrl = conn.getURL();// 获得真实Url
// System.out.println(absUrl.toString());
// 打印输出服务器Header信息
// Map<String, List<String>> map = conn.getHeaderFields();
// for (String str : map.keySet()) {
// System.out.println(str + " " + map.get(str));
// }
String suffixes="avi|mpeg|3gp|mp3|mp4|wav|jpeg|gif|jpg|png|apk|exe|pdf|rar|zip|docx|doc";
Pattern pat= Pattern.compile("[\\w]+[\\.]("+suffixes+")");
Matcher mc=pat.matcher(absUrl.toString());
String substring="";
while(mc.find()){
substring = mc.group();
//System.out.println("filename:"+ substring);
}
return substring;
}
}
执行分割文件以及保存类
1.分段切割用到HttpUrlConnection对象的setRequestProperty(“Range”, “bytes=” + start + “-” + end)
2.分段传输用到HttpUrlConnection对象的getInputStream()方法
将已经切割好的conn对象的数据下载下来
3.RandomAccessFile seek(start)方法将每一段数据保存下来
public class DownloadWithRange implements Runnable
{
private String urlLocation; //由url获取HttpURLConnection类型
private String filePath;
private long start;
private long end;
DownloadWithRange(String urlLocation, String filePath, long start, long end)
{
this.urlLocation = urlLocation;
this.filePath = filePath;
this.start = start;
this.end = end;
}
@Override
public void run()
{
try
{
HttpURLConnection conn = getHttp();
conn.setRequestProperty("Range", "bytes=" + start + "-" + end); //setRequestProperty函数进行文件切割
File file = new File(filePath);
RandomAccessFile out = null;
if (file != null)
{
//对于待生成文件——file创建随机存取文件流
out = new RandomAccessFile(file, "rwd");
}
out.seek(start); //从start位置开始写入——seek函数
InputStream in = conn.getInputStream(); //getInputStream分段传输。这里的HttpURLConnection已经是分割后的内容了
byte[] b = new byte[1024];
int len = 0;
while ((len = in.read(b)) != -1) //inputstream read 方法取出数据流中的数据 ————read(),read(byte[] b),read(byte[] b, int off, int len)
{
out.write(b, 0, len); //把b内容写入out
}
in.close();
out.close();
}
catch (Exception e)
{
e.getMessage();
}
}
public HttpURLConnection getHttp() throws IOException
{
URL url = null;
if (urlLocation != null)
{
url = new URL(urlLocation);
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
return conn;
}
}