文件下载原里:
package com.example.thread.test import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class FileDownLoader { public static void main(String[] args) { try { FileDownLoader loader = new FileDownLoader(); loader.download(); } catch (Exception e) { } } public void download() throws Exception { String path = "http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ2013SP5.847223644.exe"; URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); conn.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, */*"); conn.setRequestProperty("Accept-Language", "zh-CN"); conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty( "User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"); conn.setRequestProperty("Connection", "Keep-Alive"); System.out.println(conn.getResponseCode()); int filesize = conn.getContentLength();// 得到文件大小 conn.disconnect(); int threasize = 3;// 线程数 File file = new File("1102.exe"); DownLoaderFile downLoaderFile = new DownLoaderFile(filesize,threasize,file); for (int i = 0; i < threasize; i++) { int startpos = i * downLoaderFile.getPerThreadSize();// 计算每条线程的下载位置 RandomAccessFile perthreadfile = new RandomAccessFile(file,"rw"); perthreadfile.seek(startpos);// 从文件的什么位置开始写入数据 new DownladerThread(i, path, startpos, downLoaderFile.getPerThreadSize(), perthreadfile).start(); } } private class DownLoaderFile{ private int perThreadSize; private RandomAccessFile accessFile; public DownLoaderFile(int fileLength, int threadSize, File file) { //将整个文件大小分成块,每个线程负责一块 this.perThreadSize=fileLength / threadSize + 1; try { accessFile=new RandomAccessFile(file, "rw"); //设置本地文件大小 accessFile.setLength(fileLength); accessFile.close(); } catch (IOException e) { e.printStackTrace(); } } public int getPerThreadSize() { return perThreadSize; } } private class DownladerThread extends Thread { // 从文件的什么位置开始下载 private int startpos; // 每条线程需要下载的文件大小 private int perthreadsize; // 下载文件的地址 private String path; // 每条线程向文件对象写入的数据 private RandomAccessFile file; // 线程id,提示每个线程下载信息 private int threadid; public DownladerThread(int threadid, String path, int startpos, int perthreadsize, RandomAccessFile perthreadfile) { this.path = path; this.startpos = startpos; this.perthreadsize = perthreadsize; this.file = perthreadfile; this.threadid = threadid; } @Override public void run() { InputStream inStream = null; try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置Http报文头字段 conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); conn.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, */*"); conn.setRequestProperty("Accept-Language", "zh-CN"); conn.setRequestProperty("Charset", "UTF-8");
//从流的什么位置开始下载 conn.setRequestProperty("Range", "bytes=" + this.startpos + "-"); //获取流对象 inStream = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; //记录当前线程下载数据的长度,它要小于当前线程下载的文件大小 int length = 0; while (length < perthreadsize && (len = inStream.read(buffer)) != -1) { file.write(buffer, 0, len); length += len;// 累计该线程下载的总大小 System.out.println(threadid + " ... "); } //释放资源 file.close(); inStream.close(); System.out.println(threadid + "线程完成下载"); } catch (Exception e) { e.printStackTrace(); } finally { if (inStream != null) { try { inStream.close(); } catch (IOException e) { inStream = null; } } } } } }
public class MulThreadDownLoad { public static void main(String[] args) throws Exception { String path="http://192.168.0.110:6118/HttpFileUploadTest/test.zip"; new MulThreadDownLoad().download(path, 3);//调用下载方法,使用3个线程下载 } /** * 下载文件的方法 * @param path * @param threadsize * @throws Exception */ private void download(String path ,int threadsize)throws Exception { URL url=new URL(path); HttpURLConnection conn= (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); if(conn.getResponseCode()==200){ int length=conn.getContentLength(); File file=new File(getFileName(path));//如果不给路径的话,那么默认的保存在 //本项目的目录底下 RandomAccessFile accessFile=new RandomAccessFile(file, "rwd"); accessFile.setLength(length); accessFile.close(); //注意:r以只读方式打开,rw:打开以便于读取和写入 /*rws:s代表的是文件的元数据,就是指的是文件的大小了等等,当设置为rws的时 候 当文件变化的时候,会自动的把文件的内容和元数据同步到手机的设备上 rwd:表示当文件变化的时候会自动的把文件的内容同步到手机设备上,而不是把文 件的元数据也 同步到手机设备上. 为了避免当手机掉电的时候,会丢失数据,那么最好采用rwd,每写一些数据就立即 同步到手机设备上 不至于数据的损坏 rw的时候,当没有这个文件的时候会创建这个文件. */ int block=length%threadsize==0? length/threadsize:length/threadsize+1; for(int threadid=0;threadid<threadsize;threadid++){ new DownloadThread(threadid,block,url,file).start(); } }else { System.out.println("下载失败!!!"); } } //创建线程类 private class DownloadThread extends Thread{ private int threadid; private int block; private URL url; private File file; public DownloadThread(int threadid, int block, URL url, File file) { this.threadid = threadid; this.block = block; this.url = url; this.file = file; } @Override public void run() { int start=threadid*block;//计算该线程从网络文件的什么位置开始下载 int end=(threadid+1)*block-1;//下载到网络文件的什么位置结束 RandomAccessFile accessFile; try { accessFile = new RandomAccessFile(file, "rwd"); accessFile.seek(start); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); conn.setRequestProperty("Range", "bytes="+start+"-"+end); //指定下载的区域是个范围byte=0-1000 //注意这里的conn.getResponseCode()==200应该是206,206才对,不然会报错 //if(conn.getResponseCode()==200){ InputStream inpuStream=conn.getInputStream(); byte[] buffer=new byte[1024]; int len=0; while((len=inpuStream.read(buffer))!=-1){ accessFile.write(buffer,0,len); } accessFile.close(); inpuStream.close(); //} System.out.println("第"+(threadid+1)+"线程已经下载完了"); } catch (Exception e) { e.printStackTrace(); } } } //得到要创建的文件名,根据路径 private String getFileName(String path) { return path.substring(path.lastIndexOf("/")+1); } }