File类
File(文件)类,我们可能会认为它指的的文件,实际上并非如此,它既能代表一个特定文件的名称,又能代表一个目录下一组文件的名称.
- 目录列表器
如果我们想查看一个目录列表,File类的list()方法可以获得FIle对象包含的所有列表,假如,我们只想获得.java结尾的文件,该怎么办呢,我们可以使用"目录过滤器",FilenameFilter类,这是一个接口,只有一个方法
boolean accept(File dir, String name);
public static String[] FileFilter(String filePath, String regex) { File file = new File(filePath); String[] fileNameList; if (StringUtils.isBlank(regex)) { fileNameList = file.list(); } else { fileNameList = file.list(new FilenameFilter() { private Pattern pattern = Pattern.compile(regex); @Override public boolean accept(File dir, String name) { return pattern.matches(regex, name); } }); } // 首字母排序 Arrays.sort(fileNameList, String.CASE_INSENSITIVE_ORDER); return fileNameList; }
file.list(new FilenameFilter())方法,FilenameFilter类是个接口,我们可以定义自己的类实现它,很明显这是策略模式的列子,我们可以过滤.java的文件,.class的文件.......
accept()方法提供给list()使用,使list()可以回调accept()方法,进而决定哪些文件包含在列表中.
这里用到了Pattern对象,也就是正则表达式对象,下一讲我们讲这个.
- 目录实用工具
下面的实用工具类可以通过使用local()方法产生由本地目录中文件构成的File对象数组,或者通过walk()方法产生给定目录下由整个目录树中所有文件构成的List<File>,这些文件是基于你的正则表达式筛选出来的.
public final class Directory { public static void main(String[] args) { System.out.println(walk("D:\\baiduyun\\filetest")); } public static 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(); } }); } // overloader public static File[] local(String path, final String regex) { return local(new File(path), regex); } public static class TreeInfo implements Iterable<File> { public List<File> files = new ArrayList<>(); public List<File> dirs = new ArrayList<>(); @Override public Iterator<File> iterator() { return files.iterator(); } void addAll(TreeInfo other) { files.addAll(other.files); dirs.addAll(other.dirs); } public String toString() { return "dirs: " + PPrint.pFormat(dirs) + "\n\nfiles:" + PPrint.pFormat(files); } } // 递归 static TreeInfo recurseDir(File startDir, String regex) { TreeInfo result = new TreeInfo(); for (File item : startDir.listFiles()) { if (item.isDirectory()) { result.dirs.add(item); result.addAll(recurseDir(item, regex)); } else { if (item.getName().matches(regex)) { result.files.add(item); } } } return result; } public static TreeInfo walk(String start, String regex) { return recurseDir(new File(start), regex); } public static TreeInfo walk(File start, String regex) { return recurseDir(start, regex); } // everything public static TreeInfo walk(File start) { return recurseDir(start, ".*"); } // everything public static TreeInfo walk(String start) { return recurseDir(new File(start), ".*"); } //打印格式化类 static class PPrint { public static String pFormat(Collection<?> c) { if (c.size() == 0) return "[]"; StringBuilder result = new StringBuilder("["); for (Object elem : c) { if (c.size() != 1) result.append("\n "); result.append(elem); } if (c.size() != 1) result.append("\n"); result.append("]"); return result.toString(); } public static void pprint(Collection<?> c) { System.out.println(c); } } }
local()方法,使用listFiles()来产生File数组,还使用了FilenameFilter()过滤你想要的File.
walk()方法,使用recurseDir()方法递归的遍历目录.
TreeInfo.toString(),是个打印方法,以便输出的信息更容易浏览.
- 目录的检查与创建
File类不仅仅代表存在的文件合目录,也可以用File类创建新的目录或整个目录路径.还可以查看文件的特性(大小,最后修改日期,读写),检查某个File对象代表的一个文件还是一个目录,并可以删除文件,下面展示File的一些用法.
public static void fileData(File file) { System.out.println( "Absolute path :" + file.getAbsolutePath() + "\n can read:" + file.canRead()+ "\n can write:" + file.canWrite() + "\n getName:" + file.getName() + "\n getParent:" + file.getParent() + "\n length:" + file.length() + "\n lastModified:" + file.lastModified()); }