多线程下载,大概意思就是说,本地先用RandomAccessFile创建一个文件,设置好大小。把服务器端的文件分成多个块(分成几块就是几个线程),每个块对应的开启一个线程下载,形成一个文件。好处嘛,大家都知道。。速度快了呗~
老规矩,先把核心代码弄上来
线程主体内容
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=" + startIndex + "-"+ endIndex);
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
System.out.println("code:"+code);
InputStream is = conn.getInputStream();
File file = new File("temp.msi");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(startIndex);
System.out.println("第" + threadId + "个线程:写文件的开始位置:" + String.valueOf(startIndex));
byte[] buffer = new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
raf.write(buffer,0,len);
}
raf.close();
is.close();
System.out.println("线程"+threadId+"下载完毕");
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
然后是main函数核心内容
String path = "http://192.168.1.102:8080/test/zip.msi";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
if(code==200){
long size=conn.getContentLength();
blocksize=size/threadCount;
System.out.println("服务器文件大小:"+size);
File file = new File("temp.msi");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.setLength(size);
for (int i = 1; i <= threadCount; i++) {
long startIndex=(i-1)*blocksize;
long endIndex=i*blocksize-1;
if(i==threadCount){
endIndex=size;
}
System.out.println("开启线程:" + i + "下载的位置:" + startIndex + "~"+ endIndex);
new DownloadThread(i, startIndex, endIndex, path).start();
}
}
conn.disconnect();
核心内容就这么多
只有两个地方还是不太明白,一个是RandomAccessFile的相关操作,还有一个就是blocksize一会+1一会又删掉,这块得好好研究一下。
另外看了好几天HttpURLConnection的视频了,大概也了解这玩意的操作过程了
1.创建一个URL对象,姑且就叫url吧
2.调用url的openConnection()方法(囧,之前的错误就是调用了url.getContent()这玩意,查了半天错误。。。)
3.设置一堆属性(各类超时时间,请求方法。。。)
4.得到状态码,也就是getResponseCode()
5.判断一下这个状态码,一般请求成功都是200,分段文件是206,貌似现在很多框架都是判断这个状态码整除100是不是等于2,也就是说状态码是2XX的时候,基本都是成功- -~~~~
6.判断没问题之后,基本就是用InputStream接收了getInputStream()
7.对流进行操作吧。。。。。转成字符串还是写成文件。。。随你怎么整吧。。。
8.记得关闭流和连接-0-~~~
9.。。。。貌似没有了。。我想到的就这么多了= =~~~~
10......滚去碎觉............剩下明天再说,明天回学校。。该干嘛干嘛去