目录
一、效果
先来看看效果:现在有一个文件夹,其结构树如下:
执行代码(注意:此处未使用真实路径,但是目录结构吻合):
FolderRecursion.recur(new File("/test"), new FileProcessor() {
@Override
public void process(File filePath) throws Exception {
System.out.println(filePath);
}
@Override
public void onProcessStart() {}
@Override
public void onProcessFinished() {}
});
将会得到以下输出(如下图),而想要递归其他目录,或者改变对每个文件(夹)的操作时,只需更改procprocess(File)的方法体,而不必再次实现递归过程,使用起来是不是很简单?
二、实现过程
不用多说,先放上几个类(接口):
1. FileProcessor.java(核心之一)
定义一个接口,实现对每个文件的处理过程,由使用者实现具体的处理。
package yt_utils.file.recursion;
import java.io.File;
public interface FileProcessor {
void process(File filePath) throws Exception;
void onProcessStart();
void onProcessFinished();
}
2. FolderRecursion.java(核心之二)
文件夹的递归扫描在这里实现。
package yt_utils.file.recursion;
import java.io.File;
import yt_utils.file.list.ListFile;
import yt_utils.file.list.ListFolder;
public class FolderRecursion {
public static void recur(File rootFolder, FileProcessor fileProcessor) throws Exception {
fileProcessor.onProcessStart();
recurDo(rootFolder, fileProcessor);
fileProcessor.onProcessFinished();
}
private static void recurDo(File rootFile, FileProcessor fileProcessor) throws Exception {
if (!rootFile.exists())
return;
if (rootFile.isFile()) {
fileProcessor.process(rootFile);
return;
}
if (rootFile.isDirectory()) {
// process files circularly in specified folder.
File[] files = rootFile.listFiles(ListFile.getFileFilter());
for (File file : files)
fileProcessor.process(file);
// process folders circularly in specified folder.
File[] folders = rootFile.listFiles(ListFolder.getFileFilter());
for (File folder : folders)
recurDo(folder, fileProcessor);
// process specified folder itself.
fileProcessor.process(rootFile);
}
}
}
3. 其他类
这两个类是针对java.io.File.listFiles(FileFilter)的过滤器,用于过滤掉指定条件的文件。
(1)ListFile.java(过滤掉其他File,只剩文件)
package yt_utils.file.list;
import java.io.File;
import java.io.FileFilter;
public class ListFile implements FileFilter {
public static ListFile fileFilter;
public ListFile() {}
public static ListFile getFileFilter() {
if (fileFilter == null)
fileFilter = new ListFile();
return fileFilter;
}
@Override
public boolean accept(File file) {
if (file.isFile())
return true;
return false;
}
}
(2)ListFolder.java(过滤掉其他File,只剩文件夹)
package yt_utils.file.list;
import java.io.File;
import java.io.FileFilter;
public class ListFolder implements FileFilter {
public static ListFolder fileFilter;
public ListFolder() {}
public static ListFolder getFileFilter() {
if (fileFilter == null)
fileFilter = new ListFolder();
return fileFilter;
}
@Override
public boolean accept(File file) {
if (file.isDirectory())
return true;
return false;
}
}
三、使用(Samples)
使用时只需调用 FolderRecursion.recur(File rootFolder, FileProcessor fileProcessor); 这一句话,其中:
-
File rootFolder:是要进行递归的根目录。
-
FileProcessor fileProcessor:用户自己实现的对每个文件的处理过程,此处会对文件进行直接操作,请注意谨慎使用文件删除相关的方法。fileProcessor中会同时对文件和文件夹进行操作,可按需求进行判断。
在上面已经贴出了直接new一个接口传入到recur()方法中,也可以使用implements关键字实现接口,如下:
public class MyFileProcessor implements FileProcessor() {
@Override
public void process(File filePath) throws Exception {
// write your processing here
}
@Override
public void onProcessStart() {}
@Override
public void onProcessFinished() {}
}
然后再调用:FolderRecursion.recur(rootFolder, new MyFileProcessor()); 同样可以实现对文件夹的递归处理。
void onProcessStart(); 和 void onProcessFinished(); 分别是递归开始前和结束后执行的动作,可以在方法体内加入自己的逻辑。
有兴趣的朋友可以自己看一下代码,留意实现过程,可以更改扫描的逻辑,达到自己想要的效果,比如BF、DF等。有什么问题的话可以在评论里发言交流。