public class Download { // 服务器的下载地址 // public static String FILEPATH = "http://192.168.86.1:8080/1-9.zip"; public static String FILEPATH = "http://dldir1.qq.com/invc/tt/QQBrowserSetup.exe"; // 本地保存的路径 public static String DESTINATION = "D:\\"; // 下载的线程数 public static int THREADCOUNT = 5; public static void main(String[] args) throws Exception { URL url = new URL(FILEPATH); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 连接超时 conn.setConnectTimeout(5 * 1000); // 下载通过GET请求 conn.setRequestMethod("GET"); // 设置代理 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"); conn.setRequestProperty("Connection", "keep-alive"); if (conn.getResponseCode() == 200) { // 文件的大小 int contentLength = conn.getContentLength(); // 将文件分成5份 int blocksize = contentLength / THREADCOUNT; // 此类的实例支持对随机访问文件的读取和写入 // 并建立一个空的文件 RandomAccessFile randomAccessFile = new RandomAccessFile(new File(Download.DESTINATION + Download.getFileName(Download.FILEPATH)), "rwd"); randomAccessFile.setLength(contentLength); randomAccessFile.close(); conn.disconnect(); for (int i = 0; i < THREADCOUNT; i++) { // 少下载一个字节 int startpos = i * blocksize; int endpos = (i + 1) * blocksize - 1; if (i == THREADCOUNT - 1) { endpos = contentLength; } new Thread(new DownloadTask(i, startpos, endpos)).start(); } } else { System.out.println("服务器出错!"); } } // 截取文件名 public static String getFileName(String path) { return path.substring(path.lastIndexOf("/") + 1, path.length()); } } // 多线程的任务 class DownloadTask implements Runnable { public DownloadTask(int id, int startpos, int endpos) { this.id = id; this.startpos = startpos; this.endpos = endpos; } int id; int startpos; int endpos; @Override public void run() { try { URL url = new URL(Download.FILEPATH); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5 * 1000); conn.setRequestMethod("GET"); // Request only part of an entity. Bytes are numbered from 0. // eg:Range: bytes=500-999 conn.setRequestProperty("Range", "bytes=" + startpos + "-" + endpos + ""); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"); conn.setRequestProperty("Connection", "keep-alive"); // HTTP Status-Code 206: Partial Content. if (conn.getResponseCode() == 206) { InputStream is = conn.getInputStream(); RandomAccessFile randomAccessFile = new RandomAccessFile(new File(Download.DESTINATION + Download.getFileName(Download.FILEPATH)), "rwd"); // 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。 randomAccessFile.seek(startpos); int len = 0; byte[] buffer = new byte[1024]; while ((len = is.read(buffer)) != -1) { randomAccessFile.write(buffer, 0, len); } is.close(); randomAccessFile.close(); conn.disconnect(); System.out.println("线程" + id + ":下载完毕"); } } catch (IOException e) { e.printStackTrace(); } } }
Java实现多线程下载
猜你喜欢
转载自4incloud.iteye.com/blog/1997027
今日推荐
周排行