在真正学习Java I/O之前,我们先了解一个实用的操作目录及文件的类-File类
1、File类
File类不仅仅只代表存在的目录或者文件。也可以用 File 对象来创建新的文件或者尚不存在的目录路径;查看文件的特性(大小、最后修改日期、读/写);判断某一个file对象是目录还是文件;删除文件等操作。
1.1、构造方法
- new File(Sting filePath) 通过给定的路径来创建一个File实例
- new File(String parent , String child) parent是上级目录的路径,完整的路径为 parent+child
- new File(File parentFile , String child) 完整的路径为parent.getPath()+child
文件路径中的分隔符:Windows中的分隔符为’\’,在Unix/Linux中分隔符是’/’。更正确的做法是使用FIle.separatorChar来获取当前系统相应的分隔符。
1.2、File类中常用的方法
1.2.1、创建
- boolean createNewFIle() 在指定位置创建一个空文件,成功返回true,如果文件已经存在则不创建文件并返回false。
- boolean mkdir() 在指定位置创建目录,该方法只会创建最后一级目录,如果上级目录不存在就会抛出异常。
- boolean mkdirs() 指定位置创建目录,可以是多层目录。
- boolean renameTo(file desc) 重命名文件或者文件夹,可以操作非空文件夹,相当于文件的剪切。
1.2.2、删除
- boolean delete() 删除文件或者一个空文件夹,如果文件夹不为空就不能删除并返回false。
- boolean deleteOnExit() 虚拟机终止时,请求删除此路径下的文件或目录,保证程序异常退出时的临时文件被删除。
1.2.3、判断
- boolean exists() 文件或者文件夹是否存在。
- boolean isFile() 是否为一个文件,如果不存在则返回false。
- boolean isDirectory() 是否为一个目录,如果不存在则返回false。
- boolean isHidden() 是否是一个隐藏的文件或者目录。
- boolean isAbsolute() 判断该文件路径是否为绝对路径。
1.2.4、获取
- String getName() 获取当前文件或者文件夹的名称,不包括上级路径。
- String getPath() 返回文件路径。
- String getAbsolutePath() 返回文件的绝对路径,与文件是否存在无关.
- long length() 返回文件的字节数大小,如果文件不存在则返回0L,如果是文件夹也返回0L。
- long lastModified() 获取最后一次被修改的时间。
- static file[] listRoots() 返回根目录,Windows中就是所有的盘符,Linux系统返回’/’。
- String list() 返回目录下的文件或者文件夹,包含隐藏文件。
- String list(FilenameFilter filter) 返回当前目录中符合过滤条件的子文件或者子目录。
- File[] listFiles() 返回目录下的文件或者目录对象。
- File[] listFiles(FilenameFilter filter) 返回当前目录中符合过滤条件的子文件或子目录。
1.3、FilenameFilter的使用
假设我们需要遍历一个目录列表,可以使用两种方法来使用File对象。一种是不带参数的listFiles()方法,可以获得此file对象包含的全部列表。然而,有时我们需要获得一个受限的列表。假如,想要获取所有以 .java 结尾的文件,那么最好的方法是使用FilenameFilter。
FilenameFilter是一个接口,需要我们在代码中实现accept()方法的逻辑处理:
@FunctionalInterface
public interface FilenameFilter {
/**
* Tests if a specified file should be included in a file list.
*
* @param dir the directory in which the file was found.
* @param name the name of the file.
* @return <code>true</code> if and only if the name should be
* included in the file list; <code>false</code> otherwise.
*/
boolean accept(File dir, String name);
}
获得所有以 .java 结尾的文件对象:
package com.xiaopeng.file;
import java.io.File;
import java.io.FilenameFilter;
/**
* FilenameFilter
* 列出目录下所有已.java为后缀的文件对象
*/
public class MyFile {
public static void main(String[] args){
File file = new File("../JavaSE_Project/src/com/xiaopeng/file");
listJava(file);
}
private static void listJava(File file) {
File[] files = file.listFiles(new MyFilenameFilter()); //使用FilenameFilter
for(File f : files){
System.out.println(f.getName());
}
}
}
class MyFilenameFilter implements FilenameFilter{
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
我们在MyFilenameFilter中的accept方法里判断文件名是以 .java 结束时该方法返回true,否则返回false。查看File[] listFiles(FilenameFilter filter)会发现:
public File[] listFiles(FilenameFilter filter) {
String ss[] = list();
if (ss == null) return null;
ArrayList<File> files = new ArrayList<>();
for (String s : ss)
if ((filter == null) || filter.accept(this, s)) //针对每个对象都会调用accept方法。
files.add(new File(s, this));
return files.toArray(new File[files.size()]);
}
针对目录下的所有文件,每次遍历都会调用accept()方法判断该文件是否以 .java 结尾,若是则将该文件加入集合中。
FilenameFilter的实现方式实际是一种“策略模式”的使用,listFiles()方法实现了基本的功能,并且按照FilenameFilter的形式提供了一种策略。listFiles()方法接收FilenameFilter对象作为参数,这意味着可以传递实现FilenameFilter接口的任何对象(即就是不同的策略)为listFiles()方法服务,进而改变listFiles()输出的结果。策略模式的目的就是提供代码行为的灵活性。