import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import sn.util.PPrint;
/**
* 目录的常用工具
*
* @author zw 在程序设计中通常会对文件集进行操作,jdk提供了local()与walk()方法,
* local()产生本地文件构成的file数组,walk()产生指目录下由整个目录树 中所有文件构成的List<File>,
*/
public final class DirectoryDemo02 {
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();
}
});
}
// overload
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<File>();
public List<File> dirs = new ArrayList<File>();
public Iterator<File> iterator() {
return files.iterator();
}
void addAll(TreeInfo other) {
files.addAll(other.files);
files.addAll(other.dirs);
}
public String toString() {
return "dirs: " + PPrint.pformat(dirs) + "\n\nfiles: "
+ PPrint.pformat(files);
}
}
public static TreeInfo walk(String start, String regex) { // begin recursion
return recurseDirs(new File(start), regex);
}
public static TreeInfo walk(File start, String regex) {
return recurseDirs(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) {
if (args.length == 0) {
System.out.println(walk("."));
} else {
for (String arg : args) {
TreeInfo treeinfo = walk(arg);
System.out.println(treeinfo);
}
}
}
}
/**
* local()方法使用被称为listFile()的File.list()的变体来产生File数组,可以看到,他还使用了FilenameFilter 。
* 如果需要list而不是数组,你可以使用Arrays.asList()自己对结果进行转换。
* walk()方法将开始目录的名字转换成File对象,然后调用recurseDirs(),该方法将递归地遍历目录,并在每次递归中都收集到大量
* 的信息。为了区分普通目录和文件,返回值实际上是一个对象元组——一个list持有所有普通文件,另一个持有目录。这里,所有的域,
* 都被有意识的设置成了public,因为TreeInfo的使命只是把对象收集起来——如果你只返回list,那么就不需要将其设置为private,
* 因为,你只是返回一个对象对 ,不需要将他设置为private。注意,TreeInfo实现了Iterable<File>,它将产生文件,
* 使你拥有在文件列表的“默认迭代”,而你可以通过证明“.dirs”来指定目录。
*/
package sn.util;
import java.util.Arrays;
import java.util.Collection;
public 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(pformat(c));
}
public static void pprint(Object[] c){
System.out.println(Arrays.asList(c));
}
}
/**
* pformat方法可以从Collection中产生格式化的String,而pprint()方法使用pformat()来执行
* 其任务。注意,没有任何元素和只有一个元素这两种特例进行了不同的处理。上面还有一个用于数组的pprint()版本。
*
*
* */
注:本文的代码来自《java编程思想-第四版》,注释是由书中的所记和自己的一些理解。