上课学的一个小案例,就记下来了。
知识要点总结:
1、利用多线程来提高系统资源的利用率。
2、采用Http协议是实现对网络资源的获取。
代码如下:
package com.yc.xunlei_1;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class Xunlei {
public static void main(String[] args) {
/*这里是通过在运行时传入参数的方式,具体是指:右击选择run as-->run configurations-->选中运行项目,在arguments 下的第一个文本框输入要穿入得参数,*/
if (args.length <2 || args.length > 3) {
throw new RuntimeException(
"参数的个数不正确,USAGE:DOWNLOAD_PATH SAVE_PATH <THREAD_COUNT>");//这里要求传入参数有下载资源路径,文件保存路径,以及线程数
}
int threadCount = args.length == 2 ? 1 : Integer.parseInt(args[2]);// 下载的线程数
new Xunlei().download(args[0], args[1], threadCount);// 开始下载
}
private void download(String urlStrs, String savePath, int threadCount) {
URL url = null;
try {
url = new URL(urlStrs);// 要下载的地址对象协议,ip地址域,端口.资源)
} catch (MalformedURLException e) {
System.err.println("下载地址不正确!!");
throw new RuntimeException("下载地址不正确", e);
}
String saveFilePath = getDownloadFileSavePath(urlStrs, savePath);
long contentLenth = getContentLength(url);// 取到下载资源的长度
// 取到每一个线程下载的长度
long threadDownloadSize = contentLenth % threadCount == 0 ? contentLenth
/ threadCount
: contentLenth / threadCount + 1;
for (int i = 0; i < threadCount; i++) {
System.out.println("启动下载线程:" + (i + 1));
new Thread(new DownloadTask(saveFilePath, url, i
* threadDownloadSize, (i + 1) * threadDownloadSize - 1),
"下载线程" + (i + 1)).start();
}
}
private long getContentLength(URL url) {
HttpURLConnection httpConn = null;
try {
httpConn = (HttpURLConnection) url.openConnection();//打开连接地址,连接资源
} catch (IOException e) {
System.err.println("连接资源地址失败");
throw new RuntimeException("连接资源地址失败");
}
long contentLength = httpConn.getContentLengthLong();// 取到下载资源的长度
System.out.println("下载资源的长度:" + contentLength);
return contentLength;
}
private String getDownloadFileSavePath(String urlStrs, String savePath) {
int endPoint = urlStrs.lastIndexOf(".");
int endSeperetor = urlStrs.lastIndexOf("/");
return savePath + urlStrs.substring(endSeperetor, endPoint) + "-"
+ System.currentTimeMillis() + "-"
+ urlStrs.substring(endPoint);
}
}
package com.yc.xunlei_1;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadTask implements Runnable {
private String saveFilePath;// 存储下载文件的位置
private URL url;// 下载文件的路径
private long startLocation;
private long endLocation;
public DownloadTask(String saveFilePath, URL url, long startLocation,
long endLocation) {
super();
this.saveFilePath = saveFilePath;
this.url = url;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
@Override
public void run() {
HttpURLConnection httpConn = null;
try {
httpConn = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
System.err.println("连接资源地址失败");
throw new RuntimeException("连接资源地址失败", e);
}
RandomAccessFile raf = null;//RandowAccessFile类是用来访问那些保存数据文件,
//这里不太人性的是需要自己首先在本地创建文件夹。
try {
raf = new RandomAccessFile(saveFilePath, "rwd");//rwd:可读可写可后缀
raf.seek(startLocation);//访问文件指定位置,并进行读写
System.out.println("创建下载资源成功");
} catch (Exception e) {
System.err.println("创建下载资源失败");
throw new RuntimeException("创建下载资源失败", e);
}
long downloadLength = 0;
try {
BufferedInputStream in = new BufferedInputStream(
httpConn.getInputStream());//httpConn.getInputStrean:得到资源的输入流
byte[] bs = new byte[1024 * 1024];
int len = -1;
while ((len = in.read(bs)) != -1) {
raf.write(bs, 0, len);
downloadLength += len;
}
System.out.println(Thread.currentThread().getName() + "下载区间:"
+ startLocation + "-" + endLocation + "下载的数量是:"
+ downloadLength);
in.close();
raf.close();
} catch (IOException e) {
System.err.println("取到下载资源失败");
throw new RuntimeException("取到下载资源失败", e);
}
}
}
http://sw.bos.baidu.com/sw-search-sp/software/80b193c3ce5e8/Thunder_9.0.16.408.exe
E:\youdao
5
//这是我运行时传入参数,实现有道词典的下载;