一段简易的文件下载代码

本文介绍了一个使用Java实现的多线程HTTP下载器,该下载器能够将一个大型文件分成多个部分并行下载,最后合并成完整的文件。通过设置线程数,可以有效地提高下载速度。
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();
			}
		}

	}
}

忘记加关闭了,其实还应该加上文件锁和获取文件的信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值