File类
File既可以表示一个特定文件,也可以表示一个文件集。即directory与否!
下例中利用File读取某个目录下所有的文件,用函数.list()获取所有的文件名,组织成List
public class DirList {
public static void main(String[] args) {
// TODO Auto-generated method stub
File path=new File("E:\\xql_Books\\ReadingBooks\\Chinese");
String[] list;
list=path.list();
Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);//对文件进行排序
for(String a:list) {
System.out.println(a);
}
}
}
输出结果:
如果利用File读取单个特殊文件还用.list()就会报空指针错误:
同时还有一个问题,如果实现过滤效果呢?比如我想要某个目录下所有的后缀名为.pdf的文件呢?
首先实现(implements一下FileNameFilter接口)
实现代码如下:
public class DirFilter implements FilenameFilter{
private Pattern pattern;
public DirFilter(String regex) {
// TODO Auto-generated constructor stub
pattern=Pattern.compile(regex);
}
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return pattern.matcher(name).matches();
}
}
然后对代码稍作更改,就可以筛选出后缀名为.pdf或者.PDF的文件名:
为什么可以这样呢?因为list()接受FilenameFilter作为参数,list()会为获得的目录中的每个对象进行筛选,即代码中的accept()。
为了使文件更易于使用,可以搜索一个文件目录下所有的文件目录和文件名,需要定义一个实用的工具类(下面的代码来自java编程思想中的示例,自己写了一遍,发现贼有意思),里面涉及到内部类的使用知识、判断文件是否是目录的方法file.isDirectory()、以及递归的思想。
下面是该工具类的代码:
package com.duan;
import java.awt.print.Printable;
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 java.util.*;
public final class Directory {
//实现local方法
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();
}
});
}
//重写local方法,不同参数的重写
public static File[] local(String path,String regex) {//输入的文件名为path
return local(new File(path), regex);
}
//内部类的使用
public static class TreeInfo implements Iterator<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);
dirs.addAll(other.dirs);
}
//数据输出
public String toString() {
return "目录:"+dirs+"\n\n文件: "+files;
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public File next() {
// TODO Auto-generated method stub
return null;
}
}
//递归搜索获取整个目录信息
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;//返回的结果是一个TreeInfo
}
//添加匹配条件的walk()方法
public static TreeInfo walk(String start,String regex) {
return recurseDirs(new File(start), regex);
}
//默认的返回所有文件的walk方法
public static TreeInfo walk(File start) {
return recurseDirs(start, ".*");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(walk(new File("E:\\xql_Books\\ReadingBooks")));
}
}
下面是跑的一个实例:
但是呢?有没有发现上面输出的结果特别特别糟心?别急,书上还实现了一种灵活打印的方法PPprint:
package com.duan;
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(pformat(Arrays.asList(c)));
}
}
这样一来,输出的结果就呈现下面这个样子:
是不是顿时觉得好看了许多?
目录的检查和创建
这几个方法都很简单,可以参考https://docs.oracle.com/javase/8/docs/api/