代码改变世界

可爱的Ant——利用Ant获取文件列表

2005-07-15 14:47  FantasySoft  阅读(...)  评论(...编辑  收藏
        提到Ant,你一定会想到它在自动构建方面有着举足轻重的地位,于我而言,也仅仅是将其作为一个自动构建的工具来使用。由于各个流行的IDE都内部集成了对Ant的强大支持,因此,我使用Ant的方式就真的简单得不能再简单了:在网上找一个build file,然后针对自己的project稍作修改。这样,我就可以在IDE窗口中拖动鼠标点两下,就可以很方便地完成 project的构建了。真的太简便了,简便得让我忽略了Ant的其他强大功能。不过,是金子总会发光的。这两天,我切实地体会到了Ant不仅仅可以极好地完成自动构建的工作,而且它还是一个十分顺手的工具,极大地提高工作效率。
        事情的缘由是这样。Leader交给我了一项工作:在一个folder下面有很多以portlet结尾的文件,第一项任务就是要得到这些文件的列表;然后呢,在另外一个PageControlList. java文件中有一个Object[][]类型的变量,里面就应该装着这些文件的名字。第二项任务就是根据文件列表中的文件名在这个Object[][]变量中进行搜索,找出还有哪些文件名没有加入到这个变量中。 好了,工作任务就讲完了,是不是很简单呢?完全可以利用IDE的搜索功能一个一个去找的,不过这样做就真的是体力活了。如果Leader让我过一段时间在检查一遍,我不拿头撞墙才怪呢。看来是得找自动化一点的办法了。我一开始想到的就是自己写一段代码来搞定,但是面对着文件的操作就让人心烦。如果用Python的话,则无法利用那个PageControlList中的方法直接得到那个Object[][]的变量,又得自己写代码去找,真的划不来。正当我郁闷于无从下手的时候,我想起了Ant,想起了常用的build file中可以很简单地获得一个folder下面的文件,还可以轻松地对文件进行filter!好,就用它了。
        由于需要完成的工作比较特殊,使用Ant本身自带的task是没有办法完成的,需要写一个自定义的task。写自定义的task也是很简单的,只要extend Ant的Task类,改写execute方法即可。我把自定义的task的名字定为list,大致的代码轮廓如下:

public class List extends Task {
   
public void execute()  }
    
}
 

而在相应的XML文件中,通过taskdef引用这个自定义task,就可以在target中使用了。

<property name="prjroot" location="D:/fantasysoft/project" />
<property name="src.dir" location="${prjroot}/src/java" />
<property name="classes.dir" location="${prjroot}\web\WEB-INF\classes" />
<property name="commonroot" location="${prjroot}/common/" />
    
<target name="declare">
    
<taskdef name="list" classname="anttask.List" classpath="${classes.dir}" />
</target>
<target name="Check" depends="declare">
   
<list>
      
   
</list>
</target>
 
定好了这个框架以后,就要考虑这个task需要什么样的参数了。由于是对文件的操作,FileSet(FileSet是Ant中定义的类型,实质是文件的集合)是必须的了,我们的check的target就会扩充成这样:

<target name="Check" depends="declare">
    
<list>
       
<fileset dir="${commonroot}" casesensitive="yes">
           
<include name="**/*Portlet.xml"/>
       
</fileset>
    
</list>      
</target> 

为了在List中获得fileset,我们就得在List中增加一个Vector类型的变量装fileset。

private Vector filesets = new Vector();    
public void addFileset(FileSet fileset) 
{
    filesets.add(fileset);
}

由于FileSet类型提供了很简便的方法获得文件列表,整个任务就变得十分简单了。 我们在execute方法中增加相应的处理代码:

public void execute() {
    String[] includedFiles 
= null
;
    
for (Iterator iterator = filesets.iterator(); iterator.hasNext();) 
{
        FileSet fs 
=
 (FileSet) iterator.next();
        DirectoryScanner ds 
=
 fs.getDirectoryScanner(getProject());
        includedFiles 
=
 ds.getIncludedFiles();
    }
 
    
}

在以上代码中,includedFiles这个字符串数组里存放着我需要的文件列表。让我头痛的文件列表操作的问题就这样轻松解决了,接下来的比较工作就是小菜一碟了。
        感谢可爱的小蚂蚁,是它让我在无聊的工作中找到了一点点满足的乐趣。 :)