package lan;
/**
* @author lan
*/
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.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
public class Downloader {
private static int THREADS = 5;
/**
* @param args
*/
public static void main(String[] args) {
try {
URL url = new URL("http://43.duotegame.com/themehospital.exe");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
System.out.println("连接到" + url);
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
String name = con.getHeaderField("content-disposition");
if (name != null && name.toLowerCase().contains("filename=")) {
name = name.substring(name.indexOf("filename=") + 9);
} else {
name = con.getURL().toString();
name = name.substring(name.lastIndexOf("/") + 1);
name = URLDecoder.decode(name, "UTF-8");
}
int length = con.getContentLength();
System.out.println("开始下载:" + name + ",长度为:" + length);
RandomAccessFile raf = new RandomAccessFile("E:/down/" + name,
"rw");
FileChannel fc = raf.getChannel();
int cl = length / THREADS;
if (length == 0) {
THREADS = 1;
}
Downloader d = new Downloader();
for (int i = 0; i < THREADS; i++) {
int begin = i * cl;
int end = (i + 1) * cl;
if (i != 0) {
begin += 1;
} else if (i == THREADS - 1) {
end = length - 1;
}
d.new Downer(url, fc, begin, end).start();
}
}
con.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private class Downer extends Thread {
private URL url;
private FileChannel fc;
private int start, end;
public Downer(URL url, FileChannel fc, int start, int end) {
this.url = url;
this.fc = fc;
this.start = start;
this.end = end;
}
@Override
public void run() {
try {
System.out.println(this.getName() + "开始下载" + start + "到" + end);
HttpURLConnection con = (HttpURLConnection) url
.openConnection();
con.setRequestProperty("User-Agent", "Lan Downloader");
con.setRequestProperty("Range", "bytes=" + start + "-" + end);
if (con.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
System.out.println("Content-Range:"
+ con.getHeaderField("Content-Range"));
System.out.println("Length:" + con.getContentLength());
InputStream is = con.getInputStream();
ReadableByteChannel rbc = Channels.newChannel(is);
ByteBuffer bb = ByteBuffer.allocate(1024 * 4);
long l = 0;
while (rbc.read(bb) != -1) {
bb.flip();
int i = fc.write(bb, start + l);
l += i;
bb.clear();
}
System.out.println(this.getName() + "下载完毕");
}
con.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
忘记加关闭了,其实还应该加上文件锁和获取文件的信息
本文介绍了一个使用Java实现的多线程HTTP下载器,该下载器能够将一个大型文件分成多个部分并行下载,最后合并成完整的文件。通过设置线程数,可以有效地提高下载速度。


被折叠的 条评论
为什么被折叠?



