File 类这个名称有一定的误导性,她既可以代表一个特定的文件(eg:F:\JMS\apache-activemq-5.7.0\bin\activemq.bat);又可以代表某个目录下的一组文件(eg:F:\JMS\apache-activemq-5.7.0)
有些时候,我们需要获取指定目录下的一些文件,比如F:\javastudy\io目录下所有java文件。请看如下示例
import java.io.File; import java.util.regex.Pattern; public class FileList { /** * @param args */ public static void main(String[] args) { File file=new File("F:"+File.separator+"javastudy"+File.separator+"io"); String[] fileNames=file.list(new FileFilter(".java")); for(String item:fileNames){ System.out.println(item); } } } class FileFilter implements java.io.FilenameFilter{ private String filterName; public FileFilter(String filterName){ this.filterName=filterName; } @Override public boolean accept(File dir, String name) { if(name.endsWith(filterName)){ return true; } return false; } } class FileFilter1 implements java.io.FilenameFilter{ private Pattern pattern; public FileFilter1(String regex){ this.pattern=Pattern.compile(regex); } @Override public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }
先看下File类中list(FilenamFilterfilter)方法,源码如下:
public String[] list(FilenameFilter filter) { String names[] = list(); if ((names == null) || (filter == null)) { return names; } ArrayList v = new ArrayList(); for (int i = 0 ; i < names.length ; i++) { if (filter.accept(this, names[i])) { v.add(names[i]); } } return (String[])(v.toArray(new String[v.size()])); }
list()方法会为此目录下的每个文件名调用accept()方法,来判断该文件是否包含在内。
类FileFilter 实现了FilenameFilter接口,这个接口只需实现accept方法
import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; public final class Directory { public static final File[] local(File dir,final String regex){ return dir.listFiles(new FilenameFilter(){ private Pattern pattern=Pattern.compile(regex); @Override public boolean accept(File dir, String name) { return pattern.matcher(new File(name).getName()).matches(); } }); } public static final File[] local(String path,final String regex){ return local(new File(path),regex); } public static class TreeInfo implements Iterable<File>{ private List<File> dirs=new ArrayList<File>(); private List<File> files=new ArrayList<File>(); @Override public Iterator<File> iterator() { return files.iterator(); } void addAll(TreeInfo other){ dirs.addAll(other.dirs); files.addAll(other.files); } @Override public String toString() { return "dirs:"+PPrint.pFormat(dirs)+"\nfiles:"+PPrint.pFormat(files); } public static TreeInfo walk(File start,String regex){ return recurseDirs(start,regex); } public static TreeInfo walk(String start,String regex){ return recurseDirs(new File(start),regex); } public static TreeInfo walk(File start){ return recurseDirs(start,".*"); } public static TreeInfo walk(String start){ return recurseDirs(new File(start),".*"); } static TreeInfo recurseDirs(File startDir,String regex){ TreeInfo result=new TreeInfo(); for(File item:startDir.listFiles()){ if(item.isDirectory()){ result.dirs.add(item); result.addAll(recurseDirs(item, regex)); }else{ if(item.getName().matches(regex)){ result.files.add(item); } } } return result; } public static void main(String[] args) { System.out.println(walk("F:/javastudy")); } } } class PPrint{ public static String pFormat(Collection<?> c){ if(c.size()==0)return "[]"; StringBuilder result=new StringBuilder("["); for(Object item:c){ if(c.size()!=1){ result.append("\n"); } result.append(item); } if(c.size()!=1){ result.append("\n"); } result.append("]"); return result.toString(); } public static void pPrint(Collection<?> c){ System.out.println(pFormat(c)); } public static void pPrint(Object c){ System.out.println(pFormat(Arrays.asList(c))); } }
运行结果如下: