Apache下的FileUtils.listFiles方法简单使用技巧


http://www.cnblogs.com/LiuChunfu/p/5651956.html

一、引言

Apache提供的很多工具方法非常好用,推荐。

今天在使用的过程中使用到了org.apache.commons.io.FileUtils.listFiles方法,本文主要谈谈这个工具方法的用法。

查看源码上的说明是

复制代码
    /**
     * Finds files within a given directory (and optionally its
     * subdirectories). All files found are filtered by an IOFileFilter.
     * <p>
     * If your search should recurse into subdirectories you can pass in
     * an IOFileFilter for directories. You don't need to bind a
     * DirectoryFileFilter (via logical AND) to this filter. This method does
     * that for you.
     * <p>
     * An example: If you want to search through all directories called
     * "temp" you pass in <code>FileFilterUtils.NameFileFilter("temp")</code>
     * <p>
     * Another common usage of this method is find files in a directory
     * tree but ignoring the directories generated CVS. You can simply pass
     * in <code>FileFilterUtils.makeCVSAware(null)</code>.
     *
     * @param directory  the directory to search in
     * @param fileFilter filter to apply when finding files.
     * @param dirFilter  optional filter to apply when finding subdirectories.
     *                   If this parameter is {@code null}, subdirectories will not be included in the
     *                   search. Use TrueFileFilter.INSTANCE to match all directories.
     * @return an collection of java.io.File with the matching files
     * @see org.apache.commons.io.filefilter.FileFilterUtils
     * @see org.apache.commons.io.filefilter.NameFileFilter
     */
复制代码

大意就是:

在指定的目录中(可以指定到子目录)通过IOFileFilter过滤器查找文件。
比如:
如果你要在所有的名为"temp"的目录,你可以使用:FileFilterUtils.NameFileFilter("temp")

 二、基本使用

测试目录下的目录结构如下所示: 

复制代码
M:\FileTest
│      5.txt
├─001
│ │    1.txt
│ │    2.txt
│ │ 
│ └─011
│      bc.eddx
│      d.docx
│ 
└─002
       3.txt
       4.txt
复制代码

最开始仅仅想获取目录下的文件,如下方法:

        Collection<File> listFiles = FileUtils.listFiles(new File("M:/FileTest"), null, null);
        for (File file : listFiles) {
            System.out.println(file.getName());
        }

此处会抛出错误:

其源码如下:Parameter 'fileFilter' is null"

复制代码
    private static void validateListFilesParameters(final File directory, final IOFileFilter fileFilter) {
        if (!directory.isDirectory()) {
            throw new IllegalArgumentException("Parameter 'directory' is not a directory: " + directory);
        }
        if (fileFilter == null) {
            throw new NullPointerException("Parameter 'fileFilter' is null");
        }
    }
复制代码

可以看出,第二个针对文件的过滤器不可以为空。

换成第二种做法:利用FileFilterUtils进行文件过滤器的创建。下面代码中使用到了 FileFilterUtils.suffixFileFilter("txt") 表示过滤出文件名后缀为txt的文件,第三个参数表示通常表示是否递归查询目录,null表示递归。

复制代码
    @Test
    public void test2(){
        Collection<File> listFiles = FileUtils.listFiles(new File("M:/FileTest"), FileFilterUtils.suffixFileFilter("txt"), null);
        showFiles(listFiles);
    }

    private void showFiles(Collection<File> listFiles) {
        if (listFiles==null) {
            return;
        }
        for (File file : listFiles) {
            System.out.println(file.getName());
        }
    }
复制代码

上述方法结果是:

5.txt

稍微修改下最后一个参数,将其由null转变为DirectoryFileFilter.INSTANCE,方法将使用递归的形式来进行文件过滤扫描。

复制代码
    @Test
    public void test3(){
        Collection<File> listFiles = FileUtils.listFiles(new File("M:/FileTest"), FileFilterUtils.suffixFileFilter("txt"), DirectoryFileFilter.INSTANCE);
        showFiles(listFiles);
    }
复制代码

结果为:

1.txt
2.txt
3.txt
4.txt
5.txt

这里需要注意,如果仅仅是过滤后缀,Apache提供了更加简单的方法:

    @Test
    public void test4(){
        Collection<File> listFiles = FileUtils.listFiles(new File("M:/FileTest"), new String[]{"txt"}, true);
        showFiles(listFiles);
    }

方法说明参见上图,此处时间关系不在赘述。

三、常见文件过滤器

 从其中最灵活的方法签名中可以得到一些信息:

第二个参数是IOFilFilter fileFilter,通过查看源码的形式可以知道其为一个接口

很显然我们查看这个接口有哪些实现类就可以获得由那些FileFilter。

从上述图的记过可以看出有基于文件大小的SizeFileFilter,基于文件名称前缀的PrefixFileFilter...,具体使用情况,依照自己项目情况选择,我这里就不一一举例了(0.0 其实我也没有全部用过~~~)

复制代码
    @Test
    public void test5(){
        Collection<File> listFiles = FileUtils.listFiles(new File("M:/FileTest"), FileFilterUtils.and(EmptyFileFilter.NOT_EMPTY,new RegexFileFilter("^[0-9]+.[a-zA-z]+$")), DirectoryFileFilter.INSTANCE);
        showFiles(listFiles);
    }
复制代码

因为我的目录中只有5.txt有点内容,所以最终的结果是5.txt,上面代码中注意

FileFilterUtils.and(EmptyFileFilter.NOT_EMPTY,new RegexFileFilter("^[0-9]+.[a-zA-z]+$"))

其中表示有2个文件过滤器,其中一个是不为空的文件过滤器,另外一个是查找文件名称的过滤器,其匹配规则是:"^[0-9]+.[a-zA-z]+$" 即文件名称只能是一个或者多个数字构成,后缀由一个或多个字母构成。

~~Over

本次博文算是我最用心的一次了。。。。


java.lang.IllegalArgumentException: Parameter 'directory' is not a directory at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:293) at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:378) at com.bosssoft.hr.train.j2se.util.UtilsDemo.method4(UtilsDemo.java:133) at Test1.testUtilsDemo4(Test1.java:66) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)源码如下:public void method4(){ // 获取目录中的所有文件和子目录 Collection<File> files = FileUtils.listFiles(new File("com/bosssoft/hr/train/j2se/util"), new String[]{"*.java"},true); // 遍历文件和子目录 if (files != null) { for (File file : files) { if (file.isDirectory()) { log.info("Directory: " + file.getName()); } else { log.info("File: " + file.getName()); } } } }
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值