File(文件)这个名字有一定的误导性;我们可能认为他指待的是一个文件,实时上并非如此。他即代表一个目录下一组文件的名称,也代表一个特定文件名称。实际上FilePath(文件路径)对这个类来说是个更好的名字。以下的事例介绍了File的使用方法还有和它相关的FilenameFilter(目录过滤器)接口。
假设我们现在想获取一个目录下的所有文件,我们可以调用File的list()方法,此方法返回一个字符串数组。如果我们想获得一个受限制的列表,比如说:我只获取指定目录下扩展名为.java文件集,那么我们就要用到"目录过滤器"FilenameFilter,FilenameFilter会帮助我们筛选符合条件的File对象。FilenameFile可以过滤目录和文件。
class DirFilter implements FilenameFilter {
private Pattern pattern;
public DirFilter(String regex) {
pattern = Pattern.compile(regex);
}
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return pattern.matcher(name).matches();
}
}
在这里DirFilter 类实现了FilenameFilter接口。创建这个类DirFilter 的唯一原因就是将accept()方法提供给list()使用,使list()可以回调accept()方法,进而决定哪些文件包含在列表中。因此,这种结构也称为回调。更具体的说是一个策略模式的例子,因为list()实现了基本功能,而且按照FilenameFilter的形式提供了这个策略,以便完善list()在提供服务时所需的算法。list()接受FilenameFilter对象作为参数,这意味着我们可以传递实现了FilenameFilter接口的任何类的对象,以选择(甚至在运行时)list()方法的行为方式。策略的目的就是提供了代码行为的灵活性。accept()方法必须接受一个代表某个特定文件所在的目录(File对象),以及包含了那个文件名的String参数。记住一点:list()方法会为此目录对象下的每个文件名都调用一次accept()方法,来判读该文件是否符合我们筛选的条件,判断结果由accept()方法返回boolean值表示。
我们在程序中常见的任务就是在文件集上执行操作,这些文件集要不在一个目录中,要么遍布整个目录树中。下边的程序,分别给出了在一个目录中和在目录树中获取文件集。
public static class TreeInfo {
public List<File> file = new ArrayList<File>();// 存储文件
public List<File> dir = new ArrayList<File>();// 存储目录
void addAll(TreeInfo treeInfo) {
file.addAll(treeInfo.file);
dir.addAll(treeInfo.dir);
}
@Override
public String toString() {
return "Dir=====================================:" + pformat(dir)
+ "File=====================================:"
+ pformat(file);
}
}
/**
* 过滤指定目录下的文件
*
* @param file
* @param regex
* @return
*/
public static File[] local(File file, final String regex) {
return file.listFiles(new FilenameFilter() {
private Pattern pattern = Pattern.compile(regex);
@Override
// dir 文件所在目录 name文件名
public boolean accept(File dir, String name) {
return pattern.matcher(name).matches();
}
});
}
/**
* 带有格式化的打印机
*
* @param c
* @return
*/
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();
}
/**
* 获取文件目录路径和目录树下的所有文件并添加到TreeInfo的两个list中
*
* @param startDir
* @param regex
* @return
*/
public static TreeInfo recurseDirs(File dir, String regex) {
TreeInfo treeInfo = new TreeInfo();
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
treeInfo.dir.add(file);
treeInfo.addAll(recurseDirs(file, regex));
} else if (file.isFile())
// 根据正则表达式过滤文件名
if (file.getName().matches(regex))
treeInfo.file.add(file);
}
return treeInfo;
}
public static void main(String[] args) {// 递归遍历目录树
TreeInfo treeInfo;
if (args.length == 0)
treeInfo = recurseDirs(new File("D://temp"), "message[A-Z].log");
else
treeInfo = recurseDirs(new File(args[0]), "message[A-Z].log");
System.out.println(treeInfo);
// 获取一个目录中的文件,并根据正则表达式筛选
// File [] arrFile = local(new
// File("D://Workspaces//MyEclipse 8.x//J4//src//io"),"^.+//.(java)$");
File[] arrFile = local(new File(
"D://Workspaces//MyEclipse 8.x//J4//src//io"), ".*");// .*代表所有文件
System.out.println(arrFile.length);
System.out.println(pformat(Arrays.asList(arrFile)));
}
}
File不仅仅代表一存在的目录或文件。也可以用File对象来创建新的目录或尚不存在的整个文件路径。我们还可以查看文件的属性,例如:文件大小,最后修改日期,能否读写,删除等。下面的事例给出了File常用的方法。