简单的正则规则下载特定后缀文件[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);
	}
	@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为什么呢?实验的时候用了"" 不出任何结果 希望有人能告知 谢谢^_^

你可能感兴趣的:(java)