package com.thread.download; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; class Worker implements Runnable { //多線程下載的數量 private static int THREADS = 4; //每一個線程下載開始的位置 private int startIndex; //每一個線程下載內容的長度 private int length; //文件保存位置 private String localFile; //遠程文件的流 InputStream in; private Worker(String urlFile, String localFile, int startIndex, int length) throws IOException { this.startIndex = startIndex; this.length = length; this.localFile = localFile; init(urlFile); } /** * 主線程打開網絡文件,先分割爲指定的大小,而後開啓多線程下載 */ public Worker(String urlFile, String localFile) throws IOException { this.localFile = localFile; int contentLength = init(urlFile); int step = contentLength / THREADS; int index = 0; for (int i = 0; i < THREADS; i++) { if (i == 0) { this.startIndex = 0; this.length = step; new Thread(this).start(); } else if (i == THREADS - 1) { Worker worker = new Worker(urlFile, localFile, index, contentLength - index); new Thread(worker).start(); } else { Worker worker = new Worker(urlFile, localFile, index, step); new Thread(worker).start(); } index = index + step; } } private int init(String urlFile) throws IOException { URL url; url = new URL(urlFile); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5 * 1000); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " + "application/x-shockwave-flash, application/xaml+xml, " + "application/vnd.ms-xpsdocument, application/x-ms-xbap, " + "application/x-ms-application, application/vnd.ms-excel, " + "application/vnd.ms-powerpoint, application/msword, */*"); connection.setRequestProperty("Accept-Language", "zh-CN"); connection.setRequestProperty("Charset", "UTF-8"); connection.setRequestProperty("Connection", "Keep-Alive"); InputStream in = connection.getInputStream(); this.in = in; return connection.getContentLength(); } @Override public void run() { System.out.println(this); try { RandomAccessFile localRandomFile = new RandomAccessFile(localFile, "rw"); MappedByteBuffer buffer = localRandomFile.getChannel().map(MapMode.READ_WRITE, startIndex, length); int i = 0; in.skip(startIndex); while (i < length) { buffer.put((byte) in.read()); i++; } buffer.force(); in.close(); localRandomFile.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override public String toString() { return "Worker [localFile=" + localFile + ", startIndex=" + startIndex + ", length=" + length + "]"; } public static void main(String[] args) throws IOException { new Worker("http://mirrors.cnnic.cn/apache/tomcat/tomcat-7/v7.0.56/bin/apache-tomcat-7.0.56.zip", "tomcat.zip"); } }