package com.java.net;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.net.URLConnection;
class Download extends Thread{
//定义字节数组(取水的竹筒)的长度
private final int BUFF_LEN = 32;
//定义下载的起始点
private long start;
//定义下载的结束点
private long end;
//下载资源对应的输入流
private InputStream is;
//将下载的字节输出到raf中
private RandomAccessFile raf;
public Download() {
}
public Download(long start, long end, InputStream is, RandomAccessFile raf) {
System.out.println(start + "---------->" + end);
this.start = start;
this.end = end;
this.is = is;
this.raf = raf;
}
@Override
public void run() {
try {
is.skip(start);
raf.seek(start);
//定义读取输入流内容的缓存数组(竹筒)
byte[] buff = new byte[BUFF_LEN];
//本线程负责下载资源的大小
long contentLen = end - start;
//定义最多需要读取几次就可以完成本线程下载
long times = contentLen / BUFF_LEN + 4;
//实际读取的字节
int hasRead = 0;
for(int i=0; i<times; i++){
hasRead = is.read(buff);
if(hasRead < 0){
break;
}
raf.write(buff, 0, hasRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(is != null) is.close();
if(raf != null) raf.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
public class MutilDown {
public static void main(String[] args) {
final int DOWN_THREAD_NUM = 4;
final String OUT_FILE_NAME = "e:/down.jpg";
InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];
try {
URL url = new URL("http://www.blueidea.com/articleimg/2006/08/3912/images/plant4.jpg");
//依次URL打开一个输入流
isArr[0] = url.openStream();
long fileLen = getFileLength(url);
System.out.println("网络资源的大小:" + fileLen);
outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");
for(int i=0; i<fileLen; i++){
outArr[0].write(0);
}
long numPerThred = fileLen / DOWN_THREAD_NUM;
//整个下载资源整除后剩下的余数
long left = fileLen % DOWN_THREAD_NUM;
for(int i=0; i<DOWN_THREAD_NUM; i++){
//为每条线程打开一条输入流,一个RandomAccessFile对象
//让每个线程分别下载文件的不同部分
if(i != 0){
//以URL打开多个输入流
isArr[i] = url.openStream();
outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
}
//分别启动多个线程来下载网络资源
if( i == DOWN_THREAD_NUM - 1){
//最后一个线程下载指定numPerThred + left个字节
new Download(i * numPerThred, (i + 1) * numPerThred + left, isArr[i],
outArr[i]).start();
}else{
//每个线程负责下载一定的numPerThred个字节
new Download(i * numPerThred, (i + 1) * numPerThred, isArr[i], outArr[i]).start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//定义获取指定网络资源的方法
public static long getFileLength(URL url) throws IOException{
long length = 0;
//打开URL对应的URLConnection
URLConnection con = url.openConnection();
long size = con.getContentLength();
length = size;
return length;
}
}