如何在给定目录下创建一个包含所有*.properties文件的File[]?

4

我有一个目录,C:\myDir

在这个目录下,可能有各种文件夹和文件。

我该如何“循环”遍历该目录,并构建一个包含所有扩展名为.properties的文件的File数组?

我想对这些文件进行一些处理,使用File[]的原因是保持其动态性(以便将来添加的其他属性文件也会被包括在内)。

我希望做类似于这样的事情:

public static void main (String[] vargs)
{

   // find all .properties files
   //

   //loop through property file and process
   {
      doSomething(myFile[i]);
   }

}

public void doSomething(File myfile) {}

如果您至少使用Java5,并且需要一个“数组”以后动态填充,最好使用List<File>而不是File[]。 - Dubas
6个回答

12

看一下FilenameFilter

final FilenameFilter filter = new FilenameFilter() {
      public boolean accept(final File directory, final String name) {
        return name.endsWith(".properties");
      }
};

强烈支持展示目前唯一一个不建议使用另一个库来完成这个基本任务的答案。File.listFiles(FilenameFilter filter)自Java 1.2以来就存在。 - Andreas Dolk
问题是关于在一个目录下查找文件,而不是在目录中查找文件。 - Brian Harris
@Brian:我看不出有什么区别,即使有,也不值得贬低,你觉得呢? - JRL
区别在于,“under”意味着递归搜索,而“in”则不是。 - Brian Harris
顺便说一下,我是在回复Andreas_D提到的File.listFiles评论。 - Brian Harris

4
您可以使用Apache Commons IO的FileUtils类来完成此操作。
FileUtils.listFiles(File directory, String[] extensions, boolean recursive);

希望这能有所帮助。

2

Using commons-io FilenameUtils

final File dir = new File("c:\\myDir");
final File[] files = dir.listFiles(new FilenameFilter() {
    @Override
    public boolean accept(final File dir, final String name) {
        return FilenameUtils.isExtension(name, "properties");
    }
});

2
实现了可递归进入目录返回文件的代码。
import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class FileList {
    public static void main(String[] args) {
        File dir = new File("/usr/local/work_apps");

        String filterExt = "properties";

        List<File> fileList = new ArrayList<File>();

        getFileteredFiles(dir,filterExt,fileList);

        for (File file : fileList) {
            System.out.println("FileList.main() "+file.getName());
        }

    }

    /**
     * Get files recursively filtered by file extention.
     * @param dir search directory for.
     * @param filterExt file extention filter.
     * @param fileList List passed to method to be filled with file's.
     */
    public static  void getFileteredFiles(File dir,String filterExt,List<File> fileList){

        if(dir.isDirectory()){
            File[] files = dir.listFiles();
            if(files != null && files.length > 0){
            for (File file : files) {
                if(file.isDirectory()){
                    getFileteredFiles(file, filterExt, fileList);
                }else{
                    if(file.getName().endsWith("."+filterExt)){
                        fileList.add(file);
                    }
                }
            }
            }
        }

    }

}

到目前为止,这是最简单的示例答案,但它似乎不能递归地在目录中搜索 :( - Jimmy
@James.Elsey 把我的代码改成了在目录中进行递归搜索 :). 这段代码实际上更简单。 - YoK
+1 现在非常优雅,您只使用了一个方法,很酷。唯一仍然困扰我的是拼写错误的方法名称(应该是filtered而不是filetered)。 - Sean Patrick Floyd
显然,您不知道Java IO包中提供的两个接口,即FilenameFilter和FileFilter。 - naikus
1
@naikus,我已经使用FilenameFilter提供了解决方案,但它没有递归遍历目录 :)。 - YoK
显示剩余3条评论

1

Apache commons IO有一个很好的用于遍历文件系统的类,叫做DirectoryWalker。如果你想要递归地查找这些属性文件,请查看它。

例如,下面的代码将递归地查找目录下的图像文件,并将它们作为列表返回。

import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;

class SourceImageFinder extends DirectoryWalker {

    public SourceImageFinder() {
        // visible directories and image files
        super(new AndFileFilter(notHiddenFileFilter(), new OrFileFilter(imageFileFilter(), DirectoryFileFilter.INSTANCE)), -1);
    }

    public List<File> findSourceImages(File directory) {
        List<File> results = Lists.newArrayList();
        try {
            walk(directory, results);
        } catch (IOException ex) {
            throw new RuntimeException("Problem finding images", ex);
        }
        return results;
    }

    @Override
    protected void handleFile(File file, int depth, Collection results) throws IOException {
        results.add(file);
    }

    private static IOFileFilter notHiddenFileFilter() {
        // HiddenFileFilter.HIDDEN doesn't exclude files starting with '.' on Windows but I want to.
        return new NotFileFilter(new OrFileFilter(HiddenFileFilter.HIDDEN, new PrefixFileFilter(".")));
    }

    private static IOFileFilter imageFileFilter() {
        return new SuffixFileFilter(new String[]{"png", "jpg", "jpeg", "gif", "bmp", "tif", "tiff"}, IOCase.INSENSITIVE);
    }
}

你可以通过添加静态导入import static org.apache.commons.io.filefilter.FileFilterUtils.*并使用工厂方法如andFileFilter()notFileFilter()等来减少许多新的BlaFilter()调用。 - Sean Patrick Floyd

1

这里是一个完整的答案,不需要外部库:

public class FileFinder{

    public static List<File> findFiles(final File baseDir, final String regex){
        final List<File> files = new ArrayList<File>();

        scanFolder(baseDir, Pattern.compile(regex), files);
        return files;
    }

    private static void scanFolder(final File dir,
        final Pattern pattern,
        final List<File> files){

        for(final File candidate : dir.listFiles()){
            if(candidate.isDirectory()){
                scanFolder(candidate, pattern, files);
            } else if(pattern.matcher(candidate.getName()).matches()){
                files.add(candidate);
            }
        }
    }

}

像这样调用:

public static void main(String[] args){
    List<File> filesAsList = FileFinder.findFiles(
                                new File("c:\\my\\dir"), ".*\\.properties");
    File[] filesAsArray = filesAsList.toArray(new File[filesAsList.size()]);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接