多线程并行下载的核心特点就是分段,并行下载。
比如一个文件200M,分5个线程,那么就给砍成5份,分别同时下就好了。速度当然比一点点下载来的要快的多。
package com.javaer.examples.file;
import java.io.File;
import java.io.FileWriter;
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.net.URLConnection;
public class MyMutilDown {
/**
* 单线程的远程下载
*/
public void SingleDown(String filePath, String url) {
try {
// 要写入的文件
File file = new File(filePath + getFileExtName(url));
FileWriter fWriter = new FileWriter(file);
URL ul = new URL(url);
URLConnection conn = ul.openConnection();
conn.setConnectTimeout(2000);// 请求超时时间
// int len = conn.getContentLength();
InputStream in = conn.getInputStream();
// byte[] by = new byte[1024];
int temp = 0;
while ((temp = in.read()) != -1) {
System.out.println(temp);
fWriter.write(temp);
}
fWriter.close();
in.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 文件后缀名
*
* @param path
* @return
*/
public String getFileExtName(String path) {
return path.substring(path.lastIndexOf("."));
}
/**
* 测试多线程
*
* @param filePath
* 文件保存路径
* @param url
* url
* @param tnum
* 线程数量
*/
public void MutiDown(String filePath, String url, int tnum) {
try {
// 要写入的文件
final File file = new File(filePath + getFileExtName(url));
System.out.println(file.getAbsolutePath());
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");// 建立随机访问
final URL ul = new URL(url);
HttpURLConnection conn = (HttpURLConnection) ul.openConnection();
conn.setConnectTimeout(2000);// 请求超时时间
conn.setRequestMethod("GET");
int len = conn.getContentLength();// 文件长度
accessFile.setLength(len);
accessFile.close();
final int block = (len + tnum - 1) / tnum;// 每个线程下载的快大小
for (int i = 0; i < tnum; i++) {
final int a = i;
new Thread(new Runnable() {
int start = block * a;// 开始位置
int end = block * (a + 1) - 1;// 结束位置
@Override
public void run() {
HttpURLConnection conn2 = null;
RandomAccessFile accessFile2 = null;
InputStream in = null;
try {
conn2 = (HttpURLConnection) ul.openConnection();
conn2.setConnectTimeout(2000);// 请求超时时间
conn2.setRequestMethod("GET");
// TODO Auto-generated method stub
conn2.setRequestProperty("Range", "bytes=" + start
+ "-" + end + "");// 设置一般请求属性 范围
in = conn2.getInputStream();
byte[] data = new byte[1024];
int len = 0;
accessFile2 = new RandomAccessFile(file, "rwd");
accessFile2.seek(start);
while ((len = in.read(data)) != -1) {
System.out.println(a + "/" + len);
accessFile2.write(data, 0, len);//并发写入
}
System.out.println("线程:" + a + "下载完成!");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
try {
accessFile2.close();
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
MyMutilDown mydown = new MyMutilDown();
String path = "http://s2.knowsky.com/code/php/openx-220080603.rar";
// mydown.SingleDown("/", path);
mydown.MutiDown("/bbc", path, 3);
}
}
注明:本文版权属于ITeye会员 lohasle