项目结构:
FileDownload.java:
package com.wl.download; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.text.DecimalFormat; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import com.wl.util.DownLoadThread; import com.wl.util.HttpClientFactory; public class FileDownload { public static void main(String[] args) { long startTime = System.currentTimeMillis(); System.out.println(startTime); String srcFileUrl = "http://172.16.2.40:80/2014/12/gpfqpfvlwsvka2mj39pn.mprx"; String destFilePath = "G:/download/destfile.mprx"; //获取文件的大小 long fileSize = getRemoteFileSize(srcFileUrl); /** * 每个线程需要下载的文件大小 (自行调整) */ //long unitSize = 1024 ; //多线程太多 卡死你电脑没问题 long unitSize = 1024 * 1024 * 2; //下载文件大小为 = 535.66M; 23559 millisecond //long unitSize = 1024 * 1024 * 50; //下载文件大小为 = 535.66M; 35726 millisecond //long unitSize = fileSize; //下载文件大小为 = 535.66M; 所使用时间 = 52865 millisecond //创建目的文件,并指定大小 createFile(destFilePath, fileSize); //开几个线程去下载 long threadCount = fileSize / unitSize; //写入文件的位置 long offset = 0; if (fileSize <= unitSize) { // 如果远程文件尺寸小于等于unitSize DownLoadThread downloadThread = new DownLoadThread(srcFileUrl, destFilePath, offset, fileSize); Thread t = new Thread(downloadThread); t.setPriority(10); t.start(); try { t.join(); //该方法作用:主线程(此处是 main函数执行的线程) 等待该下载线程结束 } catch (InterruptedException e) { } }else{ for (int i = 1; i <= threadCount; i++) { DownLoadThread downloadThread = new DownLoadThread( srcFileUrl, destFilePath, offset, unitSize); Thread t = new Thread(downloadThread); t.setPriority(10); t.start(); offset = offset + unitSize; } if (fileSize % unitSize != 0) { // 如果不能整除,则需要再创建一个线程下载剩余字节 DownLoadThread downloadThread = new DownLoadThread(srcFileUrl, destFilePath, offset, fileSize - unitSize * threadCount); Thread t = new Thread(downloadThread); t.setPriority(10); t.start(); try { t.join(); //该方法作用:主线程(此处是 main函数执行的线程) 等待所有由 主线程产生的下载线程 结束 } catch (InterruptedException e) { } } } long endTime = System.currentTimeMillis(); System.out.println(endTime); System.out.println("下载文件大小为 = " + fileSize2String(fileSize)+ "; 所使用时间 = "+ (endTime - startTime) + " millisecond"); } /** * 获取文件大小 */ private static long getRemoteFileSize(String srcFileUrl) { HttpClient httpClient = HttpClientFactory.getInstance().getHttpClient(); HttpGet httpGet = new HttpGet(srcFileUrl); // 发送请求,返回响应 HttpResponse response = null; try { response = httpClient.execute(httpGet); } catch (ClientProtocolException e) { } catch (IOException e) { } long result = response.getEntity().getContentLength(); return result; } /** * 创建指定大小的文件 * @param fileName * @param fileSize */ private static void createFile(String fileName, long fileSize) { File newFile = new File(fileName); if(newFile.exists())newFile.delete(); RandomAccessFile raf = null; try { raf = new RandomAccessFile(newFile, "rw"); raf.setLength(fileSize); } catch (FileNotFoundException e) { } catch (IOException e) { } finally { try { if (raf != null) { raf.close(); } } catch (IOException e) { } } } /** * 获取大小字符串 * @param totalSize * @return */ private static String fileSize2String(long totalSize){ String fileTotalSize=""; DecimalFormat df = new DecimalFormat("0.00"); if(totalSize <1024){ fileTotalSize=totalSize+"B"; }else if(totalSize <1048576){ fileTotalSize=df.format((float)totalSize/1024)+"K"; }else if(totalSize <1073741824){ fileTotalSize=df.format((float)totalSize/1048576)+"M"; }else{ fileTotalSize=df.format((float)totalSize/1073741824)+"G"; } return fileTotalSize; } }
DownLoadThread.java
package com.wl.util; import java.io.BufferedInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; public class DownLoadThread implements Runnable { private String url = null;// 待下载的文件 private String file = null;// 本地存储路径 private long offset = 0;// 偏移量 private long length = 0;// 分配给本线程的下载字节数 public DownLoadThread(String url, String file, long offset, long length) { this.url = url; this.file = file; this.offset = offset; this.length = length; } public void run() { BufferedInputStream bis = null; SaveItemFile saveItemFile = null; try { HttpURLConnection httpURLConnection = (HttpURLConnection) new URL( this.url.replace(" ", "%20")).openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setRequestProperty("RANGE", "bytes=" + this.offset + "-" + (this.offset + this.length - 1)); bis = new BufferedInputStream(httpURLConnection.getInputStream()); saveItemFile = new SaveItemFile(file,offset); byte[] buff = new byte[1024*8]; while ((length = bis.read(buff)) > 0 && offset < offset+length ) { //写入文件内容,返回最后写入的长度 offset += saveItemFile.write(buff, 0, (int)length); } } catch (IOException e) { } finally { try { if (bis != null) { bis.close(); } if(saveItemFile!=null){ saveItemFile.close(); } } catch (IOException e) { } } } }
HttpClientFactory.java:
package com.wl.util; import java.util.concurrent.TimeUnit; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; public class HttpClientFactory { private HttpClient httpClient = null; /** * 本类可能存在的惟一的一个实例 */ private static HttpClientFactory m_instance; /** * 静态工厂方法 * * @return 返还ReadConfigation 类的单一实例 */ public static HttpClientFactory getInstance() { if (null == m_instance) { m_instance = new HttpClientFactory(); } return m_instance; } private HttpClientFactory() { // 设置组件参数, HTTP协议的版本,1.1/1.0/0.9 HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1"); HttpProtocolParams.setUseExpectContinue(params, true); // 设置连接超时时间 int REQUEST_TIMEOUT = 30 * 1000; // 设置请求超时10秒钟 int SO_TIMEOUT = 10 * 1000; // 设置等待数据超时时间10秒钟 // HttpConnectionParams.setConnectionTimeout(params, REQUEST_TIMEOUT); // HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT); params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, REQUEST_TIMEOUT); params.setParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT); // 设置访问协议 SchemeRegistry schreg = new SchemeRegistry(); schreg.register(new Scheme("http", 80, PlainSocketFactory .getSocketFactory())); schreg.register(new Scheme("https", 443, SSLSocketFactory .getSocketFactory())); // 多连接的线程安全的管理器 PoolingClientConnectionManager pccm = new PoolingClientConnectionManager( schreg); pccm.setDefaultMaxPerRoute(50); // 每个主机的最大并行链接数 pccm.setMaxTotal(100); // 客户端总并行链接最大数 httpClient = new DefaultHttpClient(pccm, params); httpClient.getConnectionManager().closeIdleConnections(10, TimeUnit.SECONDS); } public DefaultHttpClient getHttpClient() { return (DefaultHttpClient) httpClient; } }
SaveItemFile.java:
package com.wl.util; import java.io.IOException; import java.io.RandomAccessFile; public class SaveItemFile { //存储文件 private RandomAccessFile itemFile; public SaveItemFile() throws IOException { this("", 0); } /** * @param name 文件路径、名称 * @param pos 写入点位置 position * @throws IOException */ public SaveItemFile(String name, long pos) throws IOException { itemFile = new RandomAccessFile(name, "rw");//可读可写 //在指定的pos位置开始写入数据 itemFile.seek(pos); } /** * <b>function:</b> 同步方法写入文件 * @author hoojo * @createDate 2011-9-26 下午12:21:22 * @param buff 缓冲数组 * @param start 起始位置 * @param length 长度 * @return */ public int write(byte[] buff, int start, int length) { int i = -1; try { itemFile.write(buff, start, length); i = length; } catch (IOException e) { e.printStackTrace(); } return i; } public void close() throws IOException { if (itemFile != null) { itemFile.close(); } } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.filedownload</groupId> <artifactId>filedownload</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>com.springsource.org.apache.httpcomponents.httpclient</artifactId> <version>4.2.1</version> </dependency> </dependencies> </project>
over
多线程上传 未完待续........
时间: 2024-10-05 10:20:57