去学校的网站下点东西 发现没有批量吐血 顿时热血澎湃啊.....不说废话了
这是咱学校网站的一个下载页:http://kczy.zjut.edu.cn/jsjwl/downloadcenter.asp?Page=2
如果chrome说有恶意程序你自己判断 因为...我们学校的神马精品课程管理系统等等都会跳
源码贴上 bug是一定有的 我测试了两次发现可以用之后就不暂时去管了
而且我还只是小白 不知道怎么测试.......
原理超简单 下载速度很慢 没用NIO的关系吧?...
好了简单说下原理
首先通过URL类的openStream方法得到输入流并且将网页下载将数据保存到一个StringBuffer对象中
对该对象的内容进行正则的匹配 匹配规则是<a href="(*.)\.后缀">
以此得到一个下载地址 然后利用多线程进行下载 通过令牌来控制线程的数量(也可以不用cachedThreadPool 而通过其他的ThreadPool并设定拒绝策略 不过我不知道怎么比较性能 就选择了自己觉得容易实现的)
package org.cc.network; /** * 用于简单下载一个网页(未加密)的特定后缀的文件 * @author Fair_jm * @version 1.0 */ import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.regex.Matcher; import java.util.regex.Pattern; public class FileDownloader { private int limit=5; private Semaphore licence=null; private ExecutorService exec=null; private String suffix="ppt"; private String base_page="http://kczy.zjut.edu.cn/jsjwl/"; private String task_page; private StringBuffer page_buffer; public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } public int getLimit() { return limit; } public void setLimit(int limit) throws Exception { if (this.limit!=licence.availablePermits()) throw new Exception("程序正在运行,无法修改"); this.limit = limit; this.licence=new Semaphore(limit); } public FileDownloader(String task_page){ this.page_buffer=new StringBuffer(); this.task_page=task_page; this.licence=new Semaphore(limit); this.exec=Executors.newCachedThreadPool(); } public FileDownloader(String task_page,String base_page){ this(task_page); this.base_page=base_page; } public FileDownloader(String task_page,String base_page,ExecutorService exec){ this(task_page,base_page); this.exec=exec; } public FileDownloader(String task_page,String base_page,ExecutorService exec,int limit){ this(task_page,base_page,exec); licence=new Semaphore(limit); this.base_page=base_page; } private void init() throws IOException{ URL url=new URL(task_page); Reader reader=new InputStreamReader(url.openStream()); char[] buf = new char[1024]; int len=0; while(!((len=reader.read(buf))<0)){ page_buffer.append(buf,0,len); } reader.close(); } public void download() throws IOException{ this.init(); Pattern pattern = Pattern.compile("<a href=\"(.*)"+"\\."+suffix+"\""); Matcher matcher = pattern.matcher(page_buffer); while(matcher.find()){ String file_page = base_page + matcher.group(1)+"."+suffix; //System.out.println(file_page); exec.submit(new DownloadHelp(file_page)); } } private class DownloadHelp implements Runnable{ private String task; private URL url; public DownloadHelp(String url) throws IOException{ this.task=url; this.url=new URL(url); } @Override public void run() { FileOutputStream fw=null; InputStream reader=null; try { FileDownloader.this.licence.acquire(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } try{ String[] names=task.split("/"); String fileName=names[names.length-1]; //System.out.println(fileName); File file=new File(FileDownloader.class.getResource(".").getPath()+fileName); reader=url.openStream(); byte[] buf = new byte[1024]; Date date_begin=new Date(); int len=0; int temp=0; while(file.exists()){ String temps=Integer.toString(temp); String name=FileDownloader.class.getResource(".").getPath()+temps+fileName; file=new File(name); temp++; //System.out.println(file.getAbsolutePath()); } //System.out.println(file.getAbsolutePath()); System.out.println(file.getName()+"启动"); file.createNewFile(); fw=new FileOutputStream(file); while(!((len=reader.read(buf))<0)){ fw.write(buf, 0, len); } Date date_end=new Date(); System.out.println(file.getName()+"完成"+"\n用时:"+(date_end.getTime()-date_begin.getTime())+"ms"); FileDownloader.this.licence.release(); }catch(IOException e){ e.printStackTrace(); }finally{ try { fw.close(); reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
测试类:
package org.cc.network; import java.io.IOException; public class Test { public static void main(String[] args) { FileDownloader fd=new FileDownloader("http://kczy.zjut.edu.cn/jsjwl/downloadcenter.asp?Page=2"); try { fd.download(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
没做任何美工 就直接让他显示结果:
020101025111274266.ppt启动 02010102511822860.ppt启动 0201010251110374374.ppt启动 0201010251110374374.ppt完成 用时:11982ms 020101025111274266.ppt完成 用时:13411ms 02010102511822860.ppt完成 用时:15095ms
改变后缀可以下载不同的文件 如果要下载多种后缀的文件 可以自己把我源代码拿去随便改 只要加个List或Set(更好吧.) 先保存下载地址就可以了吧
还有 因为用了cachedThreadPool 所以要下载结束后60s才会自动退出 这点请留意
如看到其他地方有此文 作者应该均是fair_jm。
ps:如果要下载所有后缀 那么设定那个suffix为什么呢?实验的时候用了"" 不出任何结果 希望有人能告知 谢谢^_^