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; } }