`

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

0
1
分享到:
评论

相关推荐

    2023年最完整区号/国家/手机号正则数据库

    3. 手机号码格式:可能包含数字分段、前缀和后缀等规则,例如中国的手机号码通常是11位数字,分为3-4-4的结构。 对于标签中的“c#”,这表明该数据库可能有与C#语言相关的实现或者示例,可能是提供了C#库或代码片段...

    处理后缀msg的邮件文件

    本篇文章将详细探讨如何使用Java编程语言来处理这类文件,以及如何根据特定需求过滤邮件内容。 首先,我们需要了解`.msg`文件的结构。`.msg`文件是一种二进制格式,包含了邮件的所有信息,如发件人、收件人、主题、...

    Java实现的模糊匹配某文件夹下的文件并删除功能示例

    总结,这个Java示例提供了基本的文件操作功能,可以扩展以支持更复杂的模糊匹配规则,如正则表达式匹配,或者增加日志记录、权限检查等增强功能。在实际开发中,理解并掌握这些基础操作对于处理文件系统任务至关重要...

    java代码计算行数

    这可以通过解析源代码文件并识别特定的语法结构来实现。 要创建一个Java工具类来完成这个任务,我们可以遵循以下步骤: 1. **读取文件**:使用Java的`java.io.File`类来定位项目目录,并获取所有.java源代码文件。...

    批量修改文件名及后缀

    在IT领域,批量修改文件名和后缀是一项常见的任务,特别是在处理大量文件时,手动更改每个文件的名称或扩展名会非常耗时且效率低下。批量操作能够大大提高工作效率,节省宝贵的时间。以下是一些关于如何批量修改...

    模拟文件类型的筛选器

    例如,在Unix/Linux中,可以使用`find`命令配合`-name`选项来查找特定后缀的文件;在Windows中,可以使用`dir`命令配合通配符(*和?)进行筛选。 2. **编程语言实现**:通过编程语言可以构建更强大的文件筛选器。...

    Java 实现文件批量重命名亲测可用(精简版)

    总的来说,Java通过其强大的IO库和面向对象的设计原则,使得实现文件批量重命名这样的任务变得简单而高效。通过对代码的适当调整和优化,我们可以创建出一个既稳定又高效的文件管理工具,满足各种文件重命名需求。

    java实现关于字符串的符号匹配帮助类

    4. **customPatternMatch(String input, char[] pattern)**:如果需要实现自定义的模式匹配,可以创建一个方法,使用栈(如`Stack.java`文件所示)来存储和检查字符序列。例如,检查输入字符串是否符合括号平衡: ``...

    批量修改文件名软件源码

    这些规则可能包括替换特定字符、添加前缀或后缀、按照日期或编号排序等。编程逻辑会根据设定的规则执行文件名的修改操作。 5. **用户界面(UI)**:虽然这里的描述没有提及,但一个完整的批量修改文件名软件往往会...

    正则表达式

    正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个单词的边界。 -或- 对正则表达式功能字符的还原,如"*"匹配它...

    简单的文件批量处理,改名改属性同名化处理

    通过编程或使用专门的文件管理工具,可以快速将一系列文件的名称按照特定规则进行更改。这可以是简单的数字递增、日期格式化,或者是更复杂的模式匹配和替换。例如,你可以将所有JPEG图片的后缀改为PNG,或者在每个...

    nginx中文件下载指定保存文件名的配置方法

    2. 在配置重命名规则时,确保正则表达式和逻辑判断正确,避免因错误配置导致文件无法下载或者文件名错误。 3. 对于参数n的安全性应当给予足够重视。理论上,任何通过URL传递的参数都可能被篡改,因此在后端应用中,...

    java源码:JS和CSS压缩混淆 JsCompressor.rar

    Java源码:JS和CSS压缩混淆 JsCompressor 是一个用于优化前端资源的工具,它能够对JavaScript和CSS文件进行压缩和混淆,以提高网页加载速度并保护代码安全。这个工具的核心在于减小文件大小,降低网络传输的时间,...

    文件名称批量修改(为文件批量添加名称标注)

    例如,可以使用Java、C#等面向对象的语言,创建一个简单的文件管理系统,实现文件的分类、标记和重命名功能。 在压缩包中的`rename`文件可能是实现批量重命名的脚本或程序源代码。对于开发者来说,查看和理解这段...

    stem_java.rar_stem ja

    而Porter Stemming算法相对简单,它通过一系列规则操作去除后缀,适用于快速但可能不够精确的处理。 在这个程序中,开发人员可能会首先对输入的英文文本进行预处理,包括分词、去除标点符号和停用词。然后,他们会...

    批量文件重命名

    这些规则可能包括但不限于数字序列、日期、添加前缀或后缀、替换特定字符串等。例如,将一系列以"image"开头的图片文件按数字顺序重命名为"image001.jpg"、"image002.jpg"等。 在给定的压缩包文件中,包含了一个名...

    讀取資料夾及檔案路徑

    3. **自定義檔案開頭名稱與副檔名名稱**: 在搜索文件时,可以使用通配符或正则表达式来匹配特定开头或具有特定后缀的文件。例如,`*txt` 将匹配所有以 ".txt" 结尾的文本文件。编程中,可以使用各种语言的内置函数,...

    文件批量修改

    2. **编程语言实现**:许多编程语言如Python、Java、C#、批处理脚本等都提供了处理文件名的API或函数库。例如,Python的os和shutil模块可以用来遍历目录,重命名文件;批处理脚本中可以使用REN命令进行文件名的替换...

    简单词法分析 编译原理实验

    在这个名为“简单词法分析 编译原理实验”的项目中,我们将深入探讨如何用C语言实现词法分析器,并通过`Reccursive.java`这个文件来理解其工作原理。 词法分析器的主要任务是识别并分割源代码中的关键字、标识符、...

Global site tag (gtag.js) - Google Analytics