简单的正则规则下载特定后缀文件[java]实现
去学校的网站下点东西 发现没有批量吐血 顿时热血澎湃啊.....不说废话了
这是咱学校网站的一个下载页: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);}@Overridepublic 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 blocke.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完成用时:11982ms020101025111274266.ppt完成用时:13411ms02010102511822860.ppt完成用时:15095ms
?
改变后缀可以下载不同的文件 如果要下载多种后缀的文件 可以自己把我源代码拿去随便改 只要加个List或Set(更好吧.) 先保存下载地址就可以了吧
还有 因为用了cachedThreadPool 所以要下载结束后60s才会自动退出 这点请留意
如看到其他地方有此文 作者应该均是fair_jm。
?
ps:如果要下载所有后缀 那么设定那个suffix为什么呢?实验的时候用了"" 不出任何结果 希望有人能告知 谢谢^_^